4

According to my opinion, the following piece of code should not compile. Yet, it does and prints perfectly:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

In fact, it does even if I remove "const" from the parameter.

void arrayTest(const int size) {

    int myArray[size];
    for(int i=0; i<size; i++) {
        myArray[i] = i;
    }
    for(int i=0; i<size; i++) {
       cout << myArray[i] << " ";
    }
    cout << endl;

}


int main() {
   arrayTest(15);
   return 0;
}

I am puzzled because I know that the size of an array is a constexp which must be evaluated at compile time. Also, I do not involve any sort of dynamic allocation (i.e. I do not use malloc(), new, etc). The function's local variables are all created on the stack. No heap involvement, whatsoever!

So, why is it compiling?

softwarelover
  • 1,009
  • 1
  • 10
  • 22
  • 2
    Some compilers (unfortunately) allow variable length arrays by default. For GCC, check this question on how to disable it: [Disable variable-length automatic arrays in gcc](https://stackoverflow.com/questions/31710642/disable-variable-length-automatic-arrays-in-gcc) – Yksisarvinen Sep 28 '19 at 21:53
  • Yksisarvinen, are you suggesting that under the hood the compiler is using dynamic allocation? – softwarelover Sep 28 '19 at 21:54
  • "Under the hood" compiler is using kind-of "dynamic allocation" _on stack_. [alloca](http://man7.org/linux/man-pages/man3/alloca.3.html). – KamilCuk Sep 28 '19 at 21:59
  • 2
    No, VLAs are allocated on the stack. You may want to look at this question: [How does the compiler allocate memory without knowing the size at compile time?](https://stackoverflow.com/questions/46387111/how-does-the-compiler-allocate-memory-without-knowing-the-size-at-compile-time) to learn what's under the hood. But still, this is not valid C++ syntax and it's only compiling because of compiler extension. – Yksisarvinen Sep 28 '19 at 22:01

1 Answers1

5

Why does C++ allow passing the array size at run-time to a function in order to construct a fixed-size array?

C++ language does not allow you to use a function parameter as the length of an array variable. The length of an array must be a compile time constant expression.

The length of myArray in your example is not a compile time constant expression, therefore the program is ill-formed.

So, why is it compiling?

Because your compiler chose to do so. The C++ language merely allows the compiler to fail compilation of ill-formed programs. They are allowed to compile succesfully, which lets the compiler to extend the language. You are using a language extension.

The C++ standard does require the compiler to diagnose ill-formed programs (except when allowed not to do so by a specific rule), and if it did not issue a diagnostic message for you, then the compiler does not conform to the standard.

Here is example output from a conforming compiler:

warning: ISO C++ forbids variable length array 'myArray' [-Wvla]

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • After adding this flag, my compiler is now considering it an error and does not compile anymore: -Werror=vla – softwarelover Sep 28 '19 at 22:08
  • @softwarelover If you're using Clang or GCC, then you can instead use the `-std=c++17 -pedantic`, which ask the compiler to conform to the particular standard given as argument. That way you aren't limiting yourself to disabling only one language extension. – eerorika Sep 28 '19 at 22:14
  • That's wonderful, eerorika. Could I use -std=c++14 -pedantic, instead of 17? – softwarelover Sep 28 '19 at 22:24
  • 1
    @softwarelover That would make the compiler conform to C++14. You can see the list of supported options in the manual of your compiler. – eerorika Sep 28 '19 at 22:25