GCC and Variable-Length Arrays

A classmate sent C ++ code with some kind of error and compiler output about this. But what surprised me most was not his problem, but the fact that an array with an unknown length at the compilation stage was created on the stack in the code. I remember at the beginning of learning a language I came across this and realized that this should not be done. Strange, but the classmate’s compiler didn’t produce other errors ...

I read somewhere that the next C ++ 14 Standard would probably allow such a trick. But the real one says that the size of the array must be constant expression. This once again reduces compatibility with C99, where VLAs have long been available.

I use GCC 4.8.1, so I decided to check on it:
void foo( int n)
{
    int array[n];
}

The compiler with the -pedantic option honestly returned:
warning: ISO C ++ forbids variable length array 'array'.

In fact, VLAs for C ++ in gcc are extensions .

Most importantly, the sizeof operator considers the size of variable-length arrays in runtime, not in compute time. Therefore, for example, we will not be able to instantiate a template with a non-type parameter using such sizeof (vla):
template 
class A
{
};
void foo(int length)
{
    int const_lenght_array[7];
    int variable_length_array[length];
    A a1; //OK
    A a2; //ERROR
}

The compiler error message nicely answers how the array size is calculated in runtime:
error: '(unsigned int) (((((sizetype) (((ssizetype) length) + -1)) + 1u) * 4u)' is not a constant expression

You can also use pointers to arrays of variable length and typedef:
int (*p)[length] = &variable_length_array;
typedef int variable_int_array_t [length];

Most of all, the GNU extension allows you to create arrays of variable length arrays of variable length, which is not allowed even for new, where only the top level can have a variable length:
void bar(int a, int b)
{
    int auto_array[a][b]; //OK
    int (*dynamic_array)[b] = new int[a][b]; //ERROR 
}

The good news is that VLAs will be introduced in C ++ 14, but are largely incompatible with the VLAs of this extension and C99. At least sizeof and typedef / using (c ++ 11) will be ill-formed for them. This will allow you not to step on the rake, expect only compliance behavior from sizeof. Here is the link to the patch for gcc.

I know that many people think that VLAs in C ++ are becoming useless: for such purposes there is a vector, and nobody cares where the memory is actually allocated for the elements. Nevertheless, the aim of the article was to show such an opportunity with gcc, so as not to be surprised later.
In conclusion, the proposal for VLAs in open-std.

Also popular now: