I\'m not a C++ expert, but as far as I know this code should fail due to size
not being constant:
#include
using namespace std;
Here is a list of new features in C99 which adds variable length arrays.
Also see $6.7.6.2/4 Array declarators of N1548(ISO/IEC 9899:201x Committee Draft — December 2, 2010 N1548) which details it.
It's a C99 feature that allows you to declare arrays like that on the stack.
c99
supports variable length arrays(VLA
) but neither c90
nor C++ supports variable length arrays, but gcc
support this as an extension in both C and C++ you can see this more clearly if you compile with these arguments:
gcc -std=c89 -pedantic
this will give you the following warning:
warning: ISO C90 forbids variable length array ‘array’ [-Wvla]
or with g++
:
g++ -pedantic
will give you this warning:
warning: ISO C++ forbids variable length array ‘array’ [-Wvla]
this standards section in the gcc
manual goes into more details. Important to note that as of the 2011 C standard variable length arrays(VLA
) are now optional.
Even without VLA extensions, the code can compile when the compiler has failed to deduce that the dimension expression is not known at compile-time. It's still UB.
Because you don't invoke g++ as a C++ compiler. If I try it, I get a warning, stating clearly that "ISO C++ forbids variable length array". But my makefiles include the option -std=c++98
, at least when I want to compile portable C++.
To allocate memory from stack or heap for a variable, the size of the variable need to be known. C++ compilers can decide themselves how they allocate memory, but c++ has made it public how they expect c++ compilers to handle the situation, and thus c++ std requires that compiler vendors publish their memory handling. This happens via sizeof operator. This operator is calculated completely in compile-time. The compile-time restriction for the array sizes comes from this requirement.
int arr[10];
std::cout << sizeof(arr) << std::endl
since every variable and type supports sizeof, their sizes need to be calculated on compile-time in c++. Thus variable-length arrays are impossible in c++.
There is another very important restriction flowing from this requirement. In principle c++ compiler vendors could calculate maximum amount of memory required for c++ program's stack, if only there weren't one problem: for recursive functions, you cannot calculate stack size used by the program, but for everything else, the size of stack can be calculated by doing the following:
Unfortunately, recursive functions break the whole scheme. And it would need global program's flow analysis to regognize which functions have possibly infinite call stacks. But the limitation for compile-time sizeof operator is important or our c++ programs would randomly run out of stack space, causing crashes and unstability. And this is unacceptable. Thus every variable and type supports compile-time sizeof operator.
VLA support requires that compilers can generate code where offsets normally generated to as constants to the resulting machine code are actually modifiable on runtime. Standard conforming c++ compilers normally do not have ability to do this. C decided to add this support and thus C compilers can do it. But in the process they needed to break the sizeof operator. No longer can the sizes be calculated on compile-time. VLA support as specified in the C standard has big problems:
These problems were already solved in c++ via std::vector which do not have any of these problems.