Are Variable Length Arrays There in C++

Are variable length arrays there in c++?

The current C++ standard does not require that compilers support VLAs. However, compiler vendors are permitted to support VLAs as an extension. GCC >= 4.7, for example, does.

It was originally proposed that VLAs would appear in C++14, however the proposal did not succeed. They also, ultimately, did not appear in C++17.

Why aren't variable-length arrays part of the C++ standard?

There recently was a discussion about this kicked off in usenet: Why no VLAs in C++0x.

I agree with those people that seem to agree that having to create a potential large array on the stack, which usually has only little space available, isn't good. The argument is, if you know the size beforehand, you can use a static array. And if you don't know the size beforehand, you will write unsafe code.

C99 VLAs could provide a small benefit of being able to create small arrays without wasting space or calling constructors for unused elements, but they will introduce rather large changes to the type system (you need to be able to specify types depending on runtime values - this does not yet exist in current C++, except for new operator type-specifiers, but they are treated specially, so that the runtime-ness doesn't escape the scope of the new operator).

You can use std::vector, but it is not quite the same, as it uses dynamic memory, and making it use one's own stack-allocator isn't exactly easy (alignment is an issue, too). It also doesn't solve the same problem, because a vector is a resizable container, whereas VLAs are fixed-size. The C++ Dynamic Array proposal is intended to introduce a library based solution, as alternative to a language based VLA. However, it's not going to be part of C++0x, as far as I know.

what happens if you create a variable length array and compile using g++

GCC documents its support of VLAs here (emphasis mine)

Variable-length automatic arrays are allowed in ISO C99, and as an
extension GCC accepts them
in C90 mode and in C++.

CLANG documentation too follows suit but mentions clearly that the standard doesn't accept (emphasis mine)

GCC and C99 allow an array's size to be determined at run time. This
extension is not permitted in standard C++
. However, Clang supports
such variable length arrays for compatibility with GNU C and C99
programs.

If you would prefer not to use this extension, you can always disable it with
-Werror=vla to disallow compilation.

What are the differences between Variable Length Arrays and Flexible Array Member?

There are two different things that the C99 standard added and they are easy to mix up by mistake:

Flexible array members. This means that a struct can have a member of unknown size at the end. Example from the C standard:

    struct s { int n; double d[]; };

int m = /* some value */;
struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));

This was used before C99 as well, but it was then undefined behavior, known as the "struct hack" referred to in another answer. Before C90, there could be unexpected padding bytes at the end of the struct, leading to bugs.

Variable length arrays (VLA). These are arrays with their size set in runtime. They are most likely implemented by the compiler by using dynamic memory allocation. Example:

void func (int n)
{
int array[n];
}

referred from user29079 : https://softwareengineering.stackexchange.com/questions/154089/c-flexible-arrays-when-did-they-become-part-of-the-standard

Is there a way to check if variable length arrays are created on stack / heap?

the array size seems too big to fit into stack, but it never complains.

By "never complains", I presume you mean that the program doesn't crash.

You never touch the memory that you allocate and the compiler was smart enough to prove it and didn't allocate anything.

Let us take the address of the variable, and send it to a function that is defined elsewhere:

int array[valone][valtwo] = {};
cout << &array << endl;

Now, the compiler wasn't quite so sure that the array is never accessed. That's because it can't go into the streaming operator which implemented in another translation unit. Perhaps the operator will dereference the pointer; we must make sure that the array exists.

Segfault crashed this program on my first attempt. The stack was overflown.


I suppose this kind of crash test is a way to test if VLA is on the stack.

Mikhail's suggestion in comments to compare adjacency of automatic variables to the VLA is a decent platform dependant idea, but it can only work if you allocate small enough VLA that it doesn't crash the program.

Is there any overhead for using variable-length arrays?

VLA does have some overhead (compared to "ordinary" named compile-time-sized array).

Firstly, it has run-time length and yet the language provides you with means to obtain the actual size of the array at run-time (using sizeof). This immediately means that the actual size of the array has to be stored somewhere. This results in some insignificant per-array memory overhead. However, since VLAs can only be declared as automatic objects, this memory overhead is not something anyone would ever notice. It is just like declaring an extra local variable of integral type.

Secondly, VLA is normally allocated on stack, but because of its variable size, in general case its exact location in memory is not known at compile time. For this reason the underlying implementation usually has to implement it as a pointer to a memory block. This introduces some additional memory overhead (for the pointer), which is again completely insignificant for the reasons described above. This also introduces slight performance overhead, since we have to read the pointer value in order to find the actual array. This is the same overhead you get when accessing malloc-ed arrays (and don't get with the named compile-time-sized arrays).

Since the size of the VLA is a run-time integer value, it can, of course, be passed as a command-line argument. VLA doesn't care where its size comes from.

VLA were introduced as run-time-sized arrays with low allocation/deallocation cost. They fit between "ordinary" named compile-time-sized arrays (which have virtually zero allocation-deallocation cost, but fixed size) and malloc-ed arrays (which have run-time size, but relatively high allocation-deallocation cost).

VLA obey [almost] the same scope-dependent lifetime rules as automatic (i.e local) objects, which means that in general case they can't replace malloc-ed arrays. They applicability is limited to situations when you need a quick run-time sized array with a typical automatic lifetime.



Related Topics



Leave a reply



Submit