The following code compiles under gcc 4.8 and Clang 3.2:
int main()
{
int size = 10;
int arr[size];
}
8.3.4/1 of the C++ Standard says that the size of an array must be an integral constant expression, which size
does not seem to be. Is this a bug in both compilers, or am I missing something?
The latest VC++ CTP rejects the code with this interesting message:
error C2466: cannot allocate an array of constant size 0
The interesting part is how it seems to think that size
is zero. But at least it rejects the code. Shouldn't gcc and Clang do the same?
The number of elements in an array is part of the array's type. As a result, the dimension must be known at compile time, which means that the dimension must be a constant expression.
The size of a signed int or unsigned int item is the standard size of an integer on a particular machine. For example, in 16-bit operating systems, the int type is usually 16 bits, or 2 bytes. In 32-bit operating systems, the int type is usually 32 bits, or 4 bytes.
The size of int[] is basically counting the number of elements inside that array. To get this we can use the sizeof() operator. If the array name is passed inside the sizeof(), then it will return total size of memory blocks that are occupied by the array.
This is variable length arrays or VLA which is a C99 feature but gcc and clang support it as an extension in C++ while Visual Studio does not. So Visual Studio
is adhering to the standard in this case and is technically correct. Not to say that extensions are bad, the Linux kernel depends on many gcc extensions, so they can be useful in certain contexts.
If you add the -pedantic
flag both gcc
and clang
will warn you about this, for example gcc
says (see it live):
warning: ISO C++ forbids variable length array 'arr' [-Wvla]
int arr[size];
^
Using the -pedantic-errors
flag will make this an error. You can read more about extensions in these documents Language Standards Supported by GCC and clangs Language Compatibility section.
Update
The draft C++ standard covers what is a integral constant expression in section 5.19
Constant expressions paragraph 3 and says:
An integral constant expression is an expression of integral or unscoped enumeration type, implicitly converted to a prvalue, where the converted expression is a core constant expression. [...]
It is not intuitively obvious from reading this what all the possibilities are but Boost's Coding Guidelines for Integral Constant Expressions does a great job of that .
In this case since you are initializing size
with a literal using const would suffice to make it an integral constant expression (see [expr.const]p2.9.1) and also bring the code back to being standard C++:
const int size = 10;
using constexpr would work too:
constexpr int size = 10;
It would probably help to read Difference between constexpr
and const
.
For reference the equivalent section to 8.3.4
paragraph 1 in the C99 draft standard would be section 6.7.5.2
Array declarators paragraph 4 which says (emphasis mine):
If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations with function prototype scope;124) such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With