27

How can I enable the use of VLAs, variable length arrays as defined in C99, in MS Visual C++ or that is not possible at all?

Yes I know that the C++ standard is based on C89 and that VLAs are not available in C89 standard and thus aren't available in C++, but MSVC++ is supposed to be a C compiler also, a behavior that can be switched on using the /TC compiler parameter (Compile as C Code (/TC)). But doing so does not seem to enable VLAs and the compiling process fails with the same errors when building as C++ (Compile as C++ Code (/TP)). Maybe MSVC++ C compiler is C89 compliant only or I am missing something (some special construct or pragma/define)?

Code sample:

#include <stdlib.h>

int main(int argc, char **argv)
{
  char pc[argc+5];

  /* do something useful with pc */

  return EXIT_SUCCESS;
}

Compile errors:

error C2057: expected constant expression

error C2466: cannot allocate an array of constant size 0

error C2133: 'pc' : unknown size

Community
  • 1
  • 1
Shinnok
  • 5,849
  • 5
  • 28
  • 44
  • C++ users should use a `std::vector` instead of a VLA. The advice does not help this question due to the C requirement, however. – jww Sep 15 '18 at 20:55

4 Answers4

28

MSVC is not a C99 compiler, and does not support variable length arrays.

At https://docs.microsoft.com/en-us/cpp/c-language/ansi-conformance MSVC is documented as conforming to C90.

Wieschie
  • 479
  • 7
  • 15
Anthony Williams
  • 62,015
  • 12
  • 122
  • 149
  • 6
    Not only that, it probably never will: http://connect.microsoft.com/VisualStudio/feedback/details/333273/request-for-c99-vla-in-visual-studio Too bad. – John Zwinck Mar 09 '11 at 14:12
  • That settles the dispute then. :-) Is there a Microsoft extension to the language that enables VLAs? GCC has one, thus enabling them for C90 and C++, besides C99 compliance. http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html – Shinnok Mar 09 '11 at 14:18
  • I think the link John provided indicates that there isn't, and won't be any time soon. – Anthony Williams Mar 09 '11 at 14:19
  • That feedback is from 2008, but that's probably the case for today also. Thanks for the answers. – Shinnok Mar 09 '11 at 14:25
  • There is no support for VLAs. MS suggest you use the C++ mode of the compiler, with std::vector as a replacement for VLAs. – Bo Persson Mar 09 '11 at 17:16
  • Just to add that yes, as of MSVS 2015, MS will only support C99 features that are also required by C++11. At this point it's settled. – Peter M Jun 28 '16 at 21:11
  • What's stupid about this is, those of us who have actually written identical data structures that are FASTER than std::vector need VLAs (responsibly used) in our implementations. Oh well, back to not supporting MSVC. Their loss, I suppose. – CodeMouse92 Mar 08 '18 at 04:10
6

VLA's are much neater to write but you can get similar behaviour using alloca() when the dynamic memory allocation of std::vector is prohibitive.

http://msdn.microsoft.com/en-us/library/x9sx5da1.aspx

Using alloca() in your example would give:

#include <stdlib.h>
#include <alloca.h>

int main(int argc, char **argv)
{
  char* pc = (char*) alloca(sizeof(char) * (argc+5));

  /* do something useful with pc */

  return EXIT_SUCCESS;
}
Bowie Owens
  • 2,488
  • 20
  • 16
  • 6
    Both `alloca` and its friend `_alloca` are deprecated in favor of `_malloca` in newer versions of msvc. And that function is so annoying to use that it is better to just declare an array of constant length and use that. – Björn Lindqvist Jan 21 '18 at 00:22
  • dont you have to free memory allocated by alloca ? – HaseeB Mir Apr 08 '18 at 00:01
  • @HaSeeBMiR No. As the memory allocated by alloca() is on the stack it is automatically reclaimed when the stack is unwound. See the documentation for your version for specifics. – Bowie Owens Apr 09 '18 at 23:40
  • @BjörnLindqvist: What do you find annoying about `_malloca()`? Explicitly calling `_freea()` will allow easy substitution of other allocation methods should the need arise, and being able to call `_freea()` in the middle of a function seems much more useful than not having any means of releasing storage before a function exits. – supercat Apr 27 '18 at 22:27
  • 3
    The main reason for using `alloca` is because stack memory is faster than heap memory. But `_malloca` isn't guaranteed to return stack memory meaning unpredictable performance in hard-to-debug edge cases when the stack is almost full. In these scenarios, you'll get impossible to debug memory leaks that doesn't otherwise happen when you forget to free the allocated memory. No tools like valgrind can help, because 99% of the time the memory is taken from the stack so the leak isn't there! Imagine debugging a memleak that only occurs on some machines because they have a smaller stack size... – Björn Lindqvist Apr 28 '18 at 09:17
6

I met same problem, this is not possible in MS Visual C++ 2015, instead you can use vector to do almost the same, only difference is neglectable overhead of heap resource manage routine(new/delete).

Although VLAs is convenient, but to allocate non-deterministic amount of memory from the stack at risk of stack overflow is generally not a good idea.

TingQian LI
  • 556
  • 5
  • 12
-1

To create a variable length array using c++, using your example, you would do something like the following:

size_t size = argc + 5;
vector<char> pc(size);

If you wanted to convert it over to std:string:

string buffer(pc.begin(), pc.end());
Jahmic
  • 9,421
  • 9
  • 54
  • 69