Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 新函数返回值的编译器行为 #包括 使用名称空间std; 内部主(空){ 整数大小=-2; int*p=新的int[size]; cout_C++_New Operator - Fatal编程技术网

C++ 新函数返回值的编译器行为 #包括 使用名称空间std; 内部主(空){ 整数大小=-2; int*p=新的int[size]; cout

C++ 新函数返回值的编译器行为 #包括 使用名称空间std; 内部主(空){ 整数大小=-2; int*p=新的int[size]; cout,c++,new-operator,C++,New Operator,因为const int size=-2;可以在编译时由编译器替换-而非const不能-编译器可以判断size为负值,并且不允许分配 编译器无法判断int*p=new int[size];是否合法,如果size不是常量-size可以在程序中或通过其他线程进行更改。const不能 无论如何,运行第一个示例都会导致未定义的行为,这是不合法的。在第一个示例中,size是一个值恰好为-2的变量,但编译器不会跟踪它,因为它是一个变量(至少出于诊断目的,我非常确定优化阶段可以跟踪它)。执行应该有问题(我不知道

因为
const int size=-2;
可以在编译时由编译器替换-而非const不能-编译器可以判断
size
为负值,并且不允许分配

编译器无法判断
int*p=new int[size];
是否合法,如果
size
不是常量-
size
可以在程序中或通过其他线程进行更改。
const
不能


无论如何,运行第一个示例都会导致未定义的行为,这是不合法的。

在第一个示例中,
size
是一个值恰好为-2的变量,但编译器不会跟踪它,因为它是一个变量(至少出于诊断目的,我非常确定优化阶段可以跟踪它)。执行应该有问题(我不知道是保证有例外还是仅仅是例外)


在第二种情况下,
size
是一个常量,因此它的值在编译时是已知的并经过验证的。

通过将其设置为常量表达式,编译器可以在编译时诊断问题。由于您将其设置为
const
,编译器可以很容易地看出该值必然为负值当您将其传递到
new


对于非常量表达式,您也会遇到同样的问题,但是编译器需要更多的智能才能检测到它。具体来说,编译器必须检测值在您初始化它的时间和您将它传递给
new
的时间之间是否没有变化。启用优化后,机会至少相当大一些编译器仍然可以/将会检测到这个问题,因为出于优化目的,它们检测数据流以便“实现”在这种情况下,该值保持不变,即使您没有将其指定为
const

第一个值会产生编译错误,因为编译器可以在编译时检测到违反了有效语法。
第二种方法产生未定义的行为[1],因为编译器在编译时无法检测到非法语法

理由:
一旦你使变量a
const
编译器知道变量
size
的值在程序执行过程中不会在任何时候改变。因此编译器将应用它的优化&只需将
const
整型
size
替换为它的常量值
-2
,其中在编译时使用时,它理解法律语法没有被折叠[1],并抱怨有错误

在第二种情况下,不添加
const
会阻止编译器应用上述优化,因为它无法确保变量
size
在程序执行过程中永远不会更改。因此它根本无法检测非法语法。然而,您最终会在r联合国时间

[1] 参考资料:
C++03 5.3.4新增[expr.New]

#include <iostream>

using namespace std;

int main(void){
    const int size = -2;
    int* p = new int[size];
    cout<<p<<endl;
    return 0;
}
常量表达式
在5.4.3/6和5.4.3/7中作了进一步解释:

noptr新声明符中的每个常量表达式应为整数常量表达式(5.19),并计算为严格的正值。
直接新声明符
中的表达式应具有非负值的整数或枚举类型(3.9.1)。[示例:如果n是int类型的变量,则
新浮点[n][5]
格式正确(因为
n
是直接新声明符的表达式),但
new float[5][n]
格式错误(因为
n
不是一个常量表达式)。如果
n
为负值,则
new float[n][5]
的效果未定义。
]

#include <iostream>

using namespace std;

int main(void){
    const int size = -2;
    int* p = new int[size];
    cout<<p<<endl;
    return 0;
}
noptr-new-declarator:
        [ expression ] attribute-specifier-seqopt
        noptr-new-declarator [ constant-expression ] attribute-specifier-seqopt