Why should global array size be an integer constant?
Asked Answered
C

4

8

In C++ I tried declaring a global array of some size. I got the error:

array bound is not an integer constant before ‘]’ token

But when I declared an array of the same type in the main() function it is working fine.

Why is there different behaviour here?

int y=5;
int arr[y];         //When I comment this line it works fine

int main()
{
    int x=5;
    int arr2[x];        // This line doesn't show any error.
}

Edit: Many are suggesting this question is a duplicate of Getting error "array bound is not an integer constant before ']' token". But that question doesn't answer why there is different behaviour.

Camion answered 10/3, 2020 at 15:25 Comment(6)
Even in main, it is not legal, it uses VLA extension.Womanhood
Bounds of all arrays, in C++, need to have a value, that is known during compilation. If such code, when placed in main is "accepted" by your compiler: you are using the compiler extension, that allows VLAs to compile, even if they are not supported by C++ standard.Rhenium
dont confuse "no compiler errors" with "is working fine". In this case "working fine" means that your code relies on a non-standard compiler provided extension, ie it is ok-ish but it isnt portable c++Oblique
Why not declare y and x as const? Do you need to modify the value of y or x? Hopefully not, because that raises many questions about how big arr and arr2 should be -- especially with repsect to initialization order. (Hint: they should be constants)Zygote
Compile your program with --std=c++17 (or --std=c++11 if it's an older compiler), and compilation will fail.Correggio
// This line doesn't show any error -- Yes it does. (rextester.com/NXZDT64108)Brenan
S
10

Both examples are ill-formed in C++. If a compiler does not diagnose the latter, then it does not conform to the standard.

Why there is a different behaviour here?

You use a language extension that allows runtime length automatic arrays. But does not allow runtime length static arrays. Global arrays have static storage.

In case you are using GCC, you can ask it to conform to the standard by using the -pedantic command line option. It is a good idea to do so in order to be informed about portability problems.

Superiority answered 10/3, 2020 at 15:29 Comment(0)
I
4

The size of an array must be a constant. You can fix this by declaring y as const.

const int y=5;
int arr[y]; 

As for why this worked in main, g++ does allow a variable length array in block scope as an extension. It is not standard C++ however.

Intergrade answered 10/3, 2020 at 15:28 Comment(0)
B
0

Both shouldn't be used, one works because (as @eerorika said) automatic length arrays are allowed on runtime, but global arrays need to have static storage.

If you want to declare an array with a variable size (e.g. given by std::cin) you would do something along the lines of:

int x;
std::cin >> x;
const int n = x;
float arr[n];

But you wouldn't be able to set it to contain just zeros with float arr[n] = {0} (if you need to add to a value in the array, not being sure you set it), you would need to use a loop like that

for(int i = 0; i < n; i++)
{
    arr[i] = 0;
}
Bloodstained answered 10/3, 2020 at 16:8 Comment(3)
Your example is still ill formed despite using const. The size must be a compile time constant expression. Something that you get from runtime input of course does not satisfy that.Superiority
The statement that “Both shouldn’t be used” is inappropriate. One might wish to avoid using a variable-length array to write portable C++ code. One might wish to use a variable-length array to achieve a desired project goal at the expense of portability. The values of these goals are subjective and circumstantial, and you cannot say where the balance lies for another person.Riedel
@EricPostpischil You're right but when you use a mutable variable, you can change it and for safety reasons it's better to keep it as a constBloodstained
A
0

The type-system of C++ handles these C-like arrays in a way that it defines arr2 from your example of type int[5]. So, yes the number of elements of the array is part of the type!

This puts some constraints on what you are allowed to use in the definition of C-like arrays. I.e. this number needs to have static storage, needs to be immutable and needs to be available at compile time.

So, you might want to change your code to something like the following, which will have another goodie. It initializes the array in a proper way:

int arr2[] = {0, 0, 0, 0, 0};   
Austen answered 9/4, 2020 at 6:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.