gcc complains: variable-sized object may not be initialized

浪子不回头ぞ 提交于 2019-12-05 05:15:30

C99 §6.7.8 Initialization says this:

The type of the entity to be initialized shall be an array of unknown size or an object type that is not a variable length array type.

So your initialization is invalid C.

The only way for type a[size] to not be a VLA is for size to be an integer constant expression (§6.7.5.2). What you have there is not an integer constant expression, so you have a VLA:

If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations with function prototype scope such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.

Part §6.6/6 Constant expressions defines them as:

An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof operator.

Actually, for my gcc (version 4.4.4), your last example

int main()
{
    const int foo=13;  
    int bar[foo+1]={0}; //wtF?
    return 0;
}

also does not compile, just as one would expect. You might want to double-check your toolchain (to verify you didn't relink an existing '.o' in there somewhere), and try again.

If you find that it really does work, here is my gcc -v output, perhaps you can detect a difference in the configuration and that might lend some light.

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) 

As Matt has already quoted the standard, const qualifier applied to an integer variable does not count as an integer constant expression. We might wonder why? It looks as innocent as an integer constant!

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.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!