Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GNU Compilers vs. Visual Studio on Arrays Allocated w/ Length Constant w/in a Scope

I'm aware that if you set a dynamic value in c/c++ you can't use that value within brackets to allocate an array (which would make it a so-called variable length array (VLA), which the current C++ standard does not support)...

i.e. See:
C++ : Variable Length Array
http://en.wikipedia.org/wiki/Variable-length_array

What I don't quite get (and what I haven't see asked precisely here) is why GNU c/c++ compilers (gcc, g++) are okay with using dynamic allocation based on an integer value (as far as I can tell) so long as that value is a constant within the scope of the array allocation, but Visual Studio's does not support this and will refuse to compile the code, spitting out errors.

e.g. in g++

void Foo(const unsigned int bar)
{
  double myStuff[bar];
  //... do stuff...
}

...compiles just fine...

But the same code refuses to compile in versions of VS I've used, unless whatever I pass to bar is const in all scopes or is a #define, static const, etc.

I would suspect that maybe GNU compilers use the scope to infer that this value is a constant within that scope and either simply assign it to a malloc or handle it specially somehow.

My questions are:

  1. Who (VS or GNU) is closer to the standard in terms of how they handle this?
  2. Is there a way to do this VS using [] on a value that's constant within scope, but not globally const throughout the entire program without a malloc call?
  3. Are there any issues I should be aware of if I use this in my GNU-compiled code?
like image 815
Jason R. Mick Avatar asked Nov 15 '13 21:11

Jason R. Mick


2 Answers

From a language point of view, VLAs are only supported in C, and only from C99 on. They are not supported in C++.

From a compiler point of view, g++ will support VLAs as extensions to C90 and C++, but if you compile with -pedantic it will disable those extensions and you'll get a compile error.

Visual Studio does not support VLAs at all in either C or C++. VS only supports up to the C89 standard, and AFAIK MS has no plans to support the later C standards at all.

As far as scope is concerned, that's defined in the C standard:

6.7.6.2 Array declarators
...
2 If an identifier is declared as having a variably modified type, it shall be an ordinary identifier (as defined in 6.2.3), have no linkage, and have either block scope or function prototype scope. If an identifier is declared to be an object with static or thread storage duration, it shall not have a variable length array type.

There are technical reasons why VLAs cannot be declared static or at file scope; objects with static storage duration are allocated at program startup and held until the program terminates, and if I'm not mistaken it's not guaranteed that objects will be allocated and initialized in any particular order. So those items need to have their size known at compile time.

like image 139
John Bode Avatar answered Sep 22 '22 23:09

John Bode


the GNU compiler collection has supported Variable Length Arrays as an extension, compile with -pedantic and you'll see the expected warning.

#include <iostream>

int main()
{
    int foo = 10;
    int bar[foo];
}

compile:

g++-4.8 -std=c++11 -O2 -pedantic -pthread main.cpp && ./a.out
main.cpp: In function ‘int main()’:
main.cpp:6:16: warning: ISO C++ forbids variable length array ‘bar’ [-Wvla]
     int bar[foo];
                ^
like image 36
Sam Miller Avatar answered Sep 24 '22 23:09

Sam Miller