Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.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++ 在编译时引用const值-何时为const';什么定义真的可用?_C++_Scope_Constants_Definition - Fatal编程技术网

C++ 在编译时引用const值-何时为const';什么定义真的可用?

C++ 在编译时引用const值-何时为const';什么定义真的可用?,c++,scope,constants,definition,C++,Scope,Constants,Definition,我试过了 const int i[] = { 1, 2, 3, 4 }; float f[i[3]]; // g++ cries "error: array bound is not an integer constant" int main() { const int j[] = { 0, 1, 2, 3 }; float g[j[3]]; // compiler is happy :) return 0; } 这两种总量之间的区别是

我试过了

const int i[] = { 1, 2, 3, 4 };
float f[i[3]]; // g++ cries "error: array bound is not an integer constant"

int main()
{
   const int j[] = { 0, 1, 2, 3 };
   float g[j[3]];                   // compiler is happy :)

   return 0;
}

这两种总量之间的区别是什么?为什么在主(内)中引用const骨料元素在全局范围内无效?<数组>中的C++大小必须是整型常量表达式(ICE)。根据定义,C++中的ICE不能包含数组中的值,而不管它是<代码> const < /C>数组。因此,在这两种情况下,
i[3]
j[3]
都不是ICE,不能用作数组声明中的大小。因此,在C++中,声明(<代码> f>代码>和<代码> g <代码>都是非法的。
但是,由于您使用的是GCC,因此在第二种情况下,非标准编译器扩展将发挥作用。当您声明一个自动数组时,GCC允许您为数组指定一个非常量大小(即运行时大小)(这基本上是C99的VLA转入C++)。这就是为什么它是“快乐”的,即使代码在C++中是不合法的。编译<代码> -ANSI -学究错误模式,您应该得到每个声明的诊断消息(错误)。C++声明中的C++大小的< /P> < P>必须是积分常量表达式(ICE)。根据定义,C++中的ICE不能包含数组中的值,而不管它是<代码> const < /C>数组。因此,在这两种情况下,
i[3]
j[3]
都不是ICE,不能用作数组声明中的大小。因此,在C++中,声明(<代码> f>代码>和<代码> g <代码>都是非法的。 但是,由于您使用的是GCC,因此在第二种情况下,非标准编译器扩展将发挥作用。当您声明一个自动数组时,GCC允许您为数组指定一个非常量大小(即运行时大小)(这基本上是C99的VLA转入C++)。这就是为什么它是“快乐”的,即使代码在C++中是不合法的。在
-ansi-pedantic error
模式下编译,您应该会得到每个声明的诊断消息(错误)。

f[i[3]]的“数组绑定不是整数常量”,这让我相信
i[3]
j[3] 
是恒定不变的,尽管我不能告诉你为什么。如果我不得不胡乱猜测的话,我会说这可能与
I
j
的地址有关,直到链接时才知道,但我真的不确定

编辑:我被打败了。把我的低劣答案留给后代。

GCC 3.4.5说“在任何函数之外声明的可变大小类型”,4.4.0说“数组绑定不是整数常量”,这让我相信
f[I[3]
j[3]
是恒定不变的,尽管我不能告诉你为什么。如果我不得不胡乱猜测的话,我会说这可能与
I
j
的地址有关,直到链接时才知道,但我真的不确定


编辑:我被打败了。留给后代的是我拙劣的答案。

编译器可以使用这些常量作为编译时常量,它可以保存在符号表中。但实际上,没有一个编译器足够复杂,可以在符号表中存储聚合,因此无法在编译时使用该值。
此外,非标准gcc扩展允许您使用可变长度的自动数组。 这就是为什么不仅如此:

const int j[] = { 0, 1, 2, 3 };
   float g[j[3]]; 
但编译器也允许这样做:

int j[] = { 0, 1, 2, 3 };
   float g[j[3]];

编译器可以将这些常量用作编译时常量,并将其保存在其符号表中。但实际上,没有一个编译器足够复杂,能够在其符号表中存储聚合,因此无法在编译时使用该值。
此外,非标准gcc扩展允许您使用可变长度的自动数组。 这就是为什么不仅如此:

const int j[] = { 0, 1, 2, 3 };
   float g[j[3]]; 
但编译器也允许这样做:

int j[] = { 0, 1, 2, 3 };
   float g[j[3]];

我明白了,我用上面提到的选项尝试了一下,让编译器再次哭泣:)但是当我尝试时,在全局范围内,
const int I=100;const int j=I+10;int k=[j+10]
即使打开了这些选项,它也可以编译。为什么?它不应该说即使
j
也不是ICE吗?legends2k:不,
j
不是ICE,因为它是基于
i
的值,而
i
不是ICE。你这次到底尝试了什么(注释中的代码看起来不完整)?什么“编译很好”?对于最初的示例,我的GCC 3.4.4报告了
-ansi-pedantic
模式下两个数组声明的错误。@AndreyT:我只是在我的全局范围内用一个空main()来尝试那个decl.。比如
const int I=100;const int j=I+10;int k[j+10];int main(int argc,char*argv[]){return 0;}
使用我的GCC 4.4.1和
-Wall-ansi-pedantic errors
可以很好地编译。没有错误或警告。@legends2k:在这些注释中的新代码中,
i
j
都是ICE,就像
j+10
一样。我明白了,我用上述选项尝试了,并再次让编译器哭喊:)但是当我尝试时,在全局范围内
const int i=100;const int j=i+10;int k=[j+10];
即使打开了这些选项,它也可以编译。为什么?它不应该说连
j
都不是冰吗?legends2k:不,
j
不是冰,因为它是基于
i
的值,而
i
不是冰。你这次到底尝试了什么(注释中的代码看起来不完整)?“编译得很好”是什么?对于最初的示例,我的GCC 3.4.4报告了
-ansi-pedantic
模式下两个数组声明的错误。@AndreyT:我只是在我的全局范围内,用一个空的main()来尝试那个decl.,比如
const int I=100;const int j=I+10;int k[j+10];int main(int argc,char*argv[]){return 0;}
使用我的GCC4.4.1和
-Wall-ansi-pedant