Why can't I initialize a variable-sized array?

21,794

Solution 1

  • The size of the array must be a constant integral expression.
  • An integral literal is a constant integral expression. (int arr[5];)
  • A constant integral variable initialized with a constant expression is a constant expression. (const int j = 4; const int i = j; int a[i];)

  • A constant variable initialized with a non-constant expression is not a constant expression

     int x = 4;  // x isn't constant expression because it is not const
     const int y = x; //therefore y is not either
     int arr[y]; //error)
    

Solution 2

It's actually more like a crazy C99 design question, since variable-length arrays are a feature from C99 that gcc allows in C++ as an extension.

In C99, 6.7.8/3 says "The type of the entity to be initialized ... is not a variable length array type", so gcc has just used the same rule for its extension as is required by C99.

The C99 rationale document doesn't say anything about why a VLA can't be initialized. I can speculate that it might be because of the risk of excess elements in the initializer, if the value provided for the size turns out to be smaller than the initializer. But I don't know.

Solution 3

From http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html "Variable-length automatic arrays are allowed in ISO C99, and as an extension GCC accepts them in C90 mode and in C++. "

Your program is not valid in c++ at all and gcc compiles it as "an extension". You'd likely have to ask the authors of gcc why they decided to implement in this way.

Solution 4

Some compilers allow this if you use const int size = 7;. Theoretically the compiler could figure out that it's constant size but it doesn't do that.

Solution 5

The code is not valid in standard C++.

As per (8.3.4.1) of the C++ standard, array size must be a constant expression

Variable lenght arrays are not allowed in C++ because C++ provides std::vector for that.

Variable length array was a feature introduced in C99 after C++ branched out from C standard based on c98. C++ already had std::vector to provide functionality of variable lenght arrays so C++ standard never allowed variable length arrays as a part of the standard.

If your compiler supports it, it is through a compiler extension. Compile with -pedantic option and it will notify you of the same with the warning saying it's forbidden by ISO C++

Share:
21,794
Lockhead
Author by

Lockhead

I write...code.

Updated on October 08, 2020

Comments

  • Lockhead
    Lockhead over 3 years

    GCC gives no error when you initialize a variable-sized array as long as the variable is const, but when it isn't, it won't compile.

    What's the reason behind this? What's so wrong with doing:

    int size = 7;
    int test[size] = {3, 4, 5};
    

    That won't compile at all, but if I don't initialize test[] then it does compile! That doesn't make any sense to me, because as far as I know a stack frame needs to be made to fit this array according to its size(7 ints) no matter what(which means the integer literals I use don't really have any meaning, if I'm not mistaken), so what difference does it make if I initialize it or not?

    Just another one of my crazy C++ design questions...

    Thanks!

  • Armen Tsirunyan
    Armen Tsirunyan almost 13 years
    Some compilers?! I think any half-decent C++ compiler must allow this since it's standard!
  • DaveR
    DaveR almost 13 years
    @MisterSir: Agreed - the STL (which std::vector is part of) wasn't even part of the the original C++ standard.
  • Damon
    Damon almost 13 years
    +1 That, and the likely reason is that it's ambiguous. An array of constant size with an initializer list initializes as many elements as are in the list and zero-initializes the rest. An array with no explicit size at all implicitly uses the initializer list's length. And what is an array with a non-const length supposed to do? Unless the non-constant length is identical to the initializer list length, it could do either.
  • Alok Save
    Alok Save almost 13 years
    @MisterSir: Hope that clear it up a bit. C standard allows VLA(variable length arrays) C++ does not!
  • Lockhead
    Lockhead almost 13 years
    The code you posted in fact does not give me any error with GCC at all. Compiles fine; which is why I'm so confused. If I change int arr[y]; to int arr[y] = {3, 2}; I will get an error. Difference? No idea.
  • Steve Jessop
    Steve Jessop almost 13 years
    @MisterSir: you forgot to specify -pedantic. Without it, gcc is not and does not attempt to be a conforming C++ implementation. You can't conclude that just because gcc accepts something, it must be syntactically correct C++.
  • Lockhead
    Lockhead almost 13 years
    I still don't understand why having one feature forces you to forbid the other. I mean, look at malloc and new.
  • Lockhead
    Lockhead almost 13 years
    I see now.. So you're saying even without initializing it's incorrect, but GCC allows it anyway? Also, compiling with -Wall and -pedantic still gives just a warning, not an error. If what you're saying is true and it's just GCC's design choice, I wonder what they were high on when they wrote it then.
  • Steve Jessop
    Steve Jessop almost 13 years
    @MisterSir: the standard only requires that incorrect programs be diagnosed by the implementation, not that they fail to compile. A warning is a diagnostic. If you want incorrect programs to fail to compile, use -pedantic-errors. It's not just GCC's design choice, it's taken from C99.
  • Lockhead
    Lockhead almost 13 years
    Might be that, but then it's just a problem with the programmer and not the language itself(as I assume most programmers know that if they wrote int size = 27, then an array's size will be of 27 elements...).
  • Alok Save
    Alok Save almost 13 years
    @MisterSir: Simply, because C++ has vector which is much better than arrays anyways.
  • Alok Save
    Alok Save almost 13 years
    @MisterSir: And i don't see which part of the answer is incorrect to be downvoted for?
  • Lockhead
    Lockhead almost 13 years
    @Als: It's based almost entirely on your own assumption. I could only upvote it after you added the part about the standard.
  • Alok Save
    Alok Save almost 13 years
    @MisterSir: VLA in C++ is such a frequently asked and discussed topic in here that I thought almost everybody is aware of it. Oh and btw it was never my assumption I was always aware of that being in the standard.
  • Lockhead
    Lockhead almost 13 years
    @Als: I'm talking about how you just said "because C++ has vectors", which is just an assumption.
  • Mankarse
    Mankarse almost 13 years
    You could also use the -std=c++98 option. See gcc.gnu.org/onlinedocs/gcc/…
  • Steve Jessop
    Steve Jessop almost 13 years
    @MisterSir: sure, but VLAs aren't designed for you to pointlessly write int size = 27; int arr[size]; instead of int arr[27];. They're designed for you to write void somefunction(int size) { int arr[size]; ... }.
  • Ciro Santilli OurBigBook.com
    Ciro Santilli OurBigBook.com over 11 years
    VLS in c++ is a GCC extension: a extra feature they decided to implement even if it is not in the c++ standard. They probably implemented it because C99 does so.
  • user180574
    user180574 almost 8 years
    This comment punches the hammer right to the nail head.