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?
有帮助吗?

解决方案

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.

其他提示

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];
                ^
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top