📜 ⬆️ ⬇️

GCC and Variable-Length Arrays

The group mate sent a C ++ code with some kind of error and a compiler output about this. But what surprised me most was not his problem, but the fact that the code created an array on the stack with an unknown length at the compilation stage. I remember that at the beginning of learning a language I ran into this and realized that it was impossible to do this. Strange, but the compiler did not give out any other errors ...

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

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

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

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

The most important thing is that the sizeof operator considers the size of arrays of variable length in runtime, and not in compaytime. Therefore, for example, we will not be able to instantiate a template with a non-type parameter using the following sizeof (vla):
 template <int p> class A { }; void foo(int length) { int const_lenght_array[7]; int variable_length_array[length]; A<sizeof(const_lenght_array)> a1; //OK A<sizeof(variable_length_array)> a2; //ERROR } 

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

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

Most of all, the GNU extension allows you to create variable-length arrays of variable-length arrays, 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, only 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 not to step on a rake, expect only size-behavior from sizeof. Here is the link to the patch for gcc.
')
I know that many people think that VLAs in C ++ become useless: there is a vector for such purposes, and nobody cares where in reality memory is allocated for elements. However, the purpose of the article was to show the possibility of gcc, so as not to be surprised.
Finally, the proposal for VLAs in open-std.

Source: https://habr.com/ru/post/195148/


All Articles