Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcc complains: variable-sized object may not be initialized

Tags:

c

gcc

gcc4

I've looked at these and they do not answer my question:

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?


I am trying to write some fairly 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 code using either:

  • 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 code compiler is not recognising const int foo=13; to be truely constant; for example we might have

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


I also realise that unlike the gcc compilers, the VS2008 compiler has no concept of C99 variable-length arrays. And that MS apparently has not mentioned any future support.


And yet, cpp code compilation with either gcc or MS compilers is altogether different/cleverer ?!

  • this fails to compile
  • but this will compile


And also what i do not understand regarding the gcc c code compiler is:

  • since this code does compile,
  • why this code does not compile..
  • and yet this code does compile?


(NB: in this last case, MS c code compilation fails; consistently as with int bar[foo]={0};)

like image 633
violet313 Avatar asked Apr 12 '12 18:04

violet313


2 Answers

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.

like image 54
Mat Avatar answered Nov 14 '22 05:11

Mat


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) 
like image 1
Edwin Buck Avatar answered Nov 14 '22 06:11

Edwin Buck