10

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!

6 Answers 6

10
  • 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)
    
Sign up to request clarification or add additional context in comments.

6 Comments

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.
@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++.
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.
@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.
You could also use the -std=c++98 option. See gcc.gnu.org/onlinedocs/gcc/…
|
6

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.

2 Comments

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...).
@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]; ... }.
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.

1 Comment

Some compilers?! I think any half-decent C++ compiler must allow this since it's standard!
4

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.

2 Comments

+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.
This comment punches the hammer right to the nail head.
3

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++

8 Comments

@MisterSir: Agreed - the STL (which std::vector is part of) wasn't even part of the the original C++ standard.
@MisterSir: Hope that clear it up a bit. C standard allows VLA(variable length arrays) C++ does not!
I still don't understand why having one feature forces you to forbid the other. I mean, look at malloc and new.
@MisterSir: Simply, because C++ has vector which is much better than arrays anyways.
@MisterSir: And i don't see which part of the answer is incorrect to be downvoted for?
|
0

I'm not sure about the intentions of gcc designers when they implemented this extension, but one possible reason why the gcc extension works like this is:

int is1[2] = {1}

compiles without warning, reasonable to assume user wants {1,0}

int is2[1] = {1,2};

compiles with a warning, what should the compiler do?

int i;
cin >> i;
int is3[i] = {1,2}

aha, to warn or not to warn?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.