我看过这些并且他们没有回答我的问题:
variable-sized object may not be initialized
C compile error: "Variable-sized object may not be initialized"
Error: Variable-sized object may not be initialized. But why?
我正在尝试编写一些相当便携的c
代码:
int main ()
{
const int foo=13;
int bar[foo]={0};
return 0;
}
使用以下任一代码编译为variable-sized object may not be initialized
代码时出现c
错误:
如果我在 VS2008 中将其编译为c
,我会得到略有不同的error C2057: expected constant expression
我明白在这里,c
代码编译器无法识别const int foo=13;
是否真正恒定;例如,我们可能有
void a(int fool)
{
const int foo=fool;
int bar[foo]={0};
}
我也意识到unlike the gcc compilers, VS2008 编译器没有C99 variable-length arrays的概念。那个MS显然没有提到任何未来的支持。
然而,使用 gcc 或 MS 编译器的cpp
代码编译完全不同/更聪明?!
关于 gcc c
代码编译器的我不理解的是:
(注意:在最后一种情况下, MS c
代码编译失败;与int bar[foo]={0};
一致
答案 0 :(得分:10)
C99§6.7.8初始化说:
要初始化的实体的类型应为未知大小的数组或不可变长度数组类型的对象类型。
所以你的初始化是无效的C.
type a[size]
不是VLA的唯一方法是size
为整数常量表达式(§6.7.5.2) 。你所拥有的不是整数常量表达式,因此你有一个VLA:
如果大小不存在,则数组类型为不完整类型。如果大小是*而不是表达式,则数组类型是未指定大小的可变长度数组类型, 它只能用于具有函数原型范围的声明,例如这些数组 尽管如此,完整的类型。如果大小是整型常量表达式且元素类型具有已知的常量大小,则数组类型不是可变长度数组类型; 否则,数组类型是可变长度数组类型。
Part§6.6/ 6 常量表达式将它们定义为:
整型常量表达式应具有整数类型,并且只能有操作数 它是整数常量,枚举常量,字符常量,sizeof 结果为整数常量的表达式,以及浮点常量 即时的演员阵容。仅在整数常量表达式中转换运算符 将算术类型转换为整数类型,但作为sizeof的操作数的一部分除外 操作
答案 1 :(得分:1)
实际上,对于我的gcc(版本4.4.4),你的最后一个例子
int main()
{
const int foo=13;
int bar[foo+1]={0}; //wtF?
return 0;
}
也没有编译,正如人们所期望的那样。您可能需要仔细检查您的工具链(以确认您没有重新链接某处的现有“.o”),然后重试。
如果你发现它确实有效,那么这是我的gcc -v
输出,也许你可以检测出配置上的差异,这可能会有所帮助。
Using built-in specs.
Target: i686-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux
Thread model: posix
gcc version 4.4.4 20100630 (Red Hat 4.4.4-10) (GCC)
答案 2 :(得分:0)
由于Matt已经引用了该标准,因此应用于整数变量的 const
限定符不计为整数常量表达式。我们可能想知道为什么它看起来像整数常量一样无辜!
此可能因为const
不是绝对的consts
。您可以通过指针更改它们的值,并且编译器可能会执行所有操作,如果它捕获了这样的赋值,则会发出警告,但是无法阻止您更改const
值。
PS:不要相信在线编译器,例如ideone.com等。这是一个非常简单的C程序的傻runtime error。