Gcc complains: variable object cannot be initialized

I looked at them and they do not answer my question:

a variable-sized object cannot be initialized

C compilation error: "Variable size object cannot be initialized"

Error: A variable-sized object cannot be initialized. But why?


I am trying to write pretty portable c code:

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


I get a variable-sized object may not be initialized error when compiling as c with:

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

And if I compile it as c in VS2008 , I get a slightly different error C2057: expected constant expression


I understand that here the c compiler does not recognize const int foo=13; to be truly permanent; for example we could have

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


I also understand that unlike gcc compilers, the VS2008 compiler has no idea about variable length arrays with variable lengths . And this MS did not seem to mention any future support.


Still, compiling cpp with gcc or MS compilers is completely different / smarter ?!


And also, what I don't understand about the gcc c compiler:


(NB: in this latter case, the MS c command is not compiled, just as with int bar[foo]={0}; )

+6
source share
3 answers

C99 Β§6.7.8 Initialization says the following:

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

So your initialization is not valid C.

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

If there is no size, the array type is incomplete. If the size is * instead of an expression, the array type is an array of variable-length arrays of indefinite size, which can only be used in declarations with function prototype space, such arrays are nonetheless full types. If the size is an integer constant expression , and the element type has a known constant size, the array type is not an array of variable length; otherwise, the array type is an array of variable length.

Part Β§6.6 / 6 Constant expressions define them as:

An integer constant expression must be an integer type and must have only operands that are integer constants, enumeration constants, character constants, sizeof expressions, the results of which are integer constants and floating constants, which are the direct operands of castings. Translation operators in integer constant expression must convert arithmetic types to integer types, except that part of the operand is for sizeof operator.

+10
source

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, as you would expect. You might want to double check your toolchain (to make sure you are not attached to an existing ".o" somewhere there) and try again.

If you find that this really works, here is my gcc -v output, you might find the difference in configuration and may give 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) 
+1
source

Since Matt has already quoted the standard, the const qualifier applied to an integer variable is not considered a constant constant expression . We may wonder why? He looks innocent, like an integer constant!

This may be because const not exactly consts . You can change your values ​​with pointers, and everything that the compiler can do, if it catches such a task at all, gives a warning, but cannot prevent you from changing the value of const .

PS: Do not trust online compilers like ideone.com etc. Here's one silly runtime error , it throws a very simple C program.

0
source

Source: https://habr.com/ru/post/913067/


All Articles