8

我看过这些,但他们没有回答我的问题:

可变大小的对象可能未初始化

C 编译错误:“可变大小的对象可能未初始化”

错误:可变大小的对象可能未初始化。但为什么?


我正在尝试编写一些相当可移植的c代码:

int main () 
{
    const int foo=13;
    int bar[foo]={0};
    return 0;
}


使用以下任一方法variable-sized object may not be initialized编译为c代码时出现错误:

  • GCC 4.3.4
  • arm-linux-gnueabi-gcc 4.4.5

如果我像cVS2008中那样编译它,我会得到一个稍微不同的error C2057: expected constant expression


我知道在这里,c代码编译器没有识别const int foo=13;出真正的常量;例如我们可能有

void a(int fool) 
{    
    const int foo=fool;
    int bar[foo]={0};
}


我还意识到,与 gcc 编译器不同VS2008编译器没有C99 可变长度数组的概念。而那个 MS 显然没有提到任何未来的支持。


然而,cpp使用gccMS编译器的代码编译完全不同/更聪明?!


而且我对gcc代码编译器的不理解是: c


(注意:在最后一种情况下,MS c代码编译失败;与 一致int bar[foo]={0};

4

3 回答 3

13

C99 §6.7.8初始化说明:

要初始化的实体的类型应该是一个未知大小的数组或一个不是可变长度数组类型的对象类型。

所以你的初始化是无效的 C.

成为 VLA的唯一方法是成为type a[size]整数常量表达式(第 6.7.5.2 节)。你所拥有的不是一个整数常量表达式,所以你有一个 VLA:size

如果大小不存在,则数组类型是不完整的类型。如果大小是 * 而不是表达式,则数组类型是未指定大小的可变长度数组类型,只能在具有函数原型范围的声明中使用,这样的数组仍然是完整类型。如果大小是整数常量表达式,并且元素类型具有已知的常量大小,则数组类型不是变长数组类型;否则,数组类型是可变长度数组类型。

第 6.6/6 部分常量表达式将它们定义为:

整数常量表达式应具有整数类型,并且应仅具有整数常量、枚举常量、字符常量、结果为整数常量的 sizeof 表达式和作为强制转换的直接操作数的浮点常量的操作数。整数常量表达式中的强制转换运算符只能将算术类型转换为整数类型,但作为 sizeof 运算符的操作数的一部分除外。

于 2012-04-12T18:39:29.730 回答
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) 
于 2012-04-12T18:34:21.020 回答
-1

正如马特已经引用了标准一样,const应用于整数变量的限定符不算作整数常量表达式。我们可能想知道为什么?它看起来像一个整数常量一样无辜!

This may be because const are not absolutely consts. You might alter their values through pointers and all a compiler might do, if at all it catches such an assignment , is throw a warning but cant really prevent you from altering the const value.

PS: Don't trust the online compilers like ideone.com etc. Here's one silly runtime error it throws for a very simple C program.

于 2012-04-12T18:47:58.477 回答