3

This is my code:

int main()
{
 const int LEN = 5;
 int x[LEN];
}

VS10 says:

error C2057: expected constant expression

error C2466: cannot allocate an array of constant size 0

error C2133: 'x' : unknown size

I even tried the the code in this page and it gives the same problem (I commented the code which gives the error, and uncommented the correct one): http://msdn.microsoft.com/en-us/library/eff825eh%28VS.71%29.aspx

If I was trying a crappy compiler, I would think it's a bug in the compiler, but it's VS2010!

Brooks Moses
  • 9,267
  • 2
  • 33
  • 57
m4design
  • 2,112
  • 3
  • 21
  • 28
  • 3
    check that LEN hasn't been #defined somewhere? – sje397 Dec 16 '10 at 06:15
  • My question is why aren't you using a `#define` for this? – William Dec 16 '10 at 06:15
  • 6
    @William: `#define`s are not a good way to define constants, because they use the preprocessor and lack typing information and such; newer languages often don't even have the equivalent. Constants like this are better practice in most situations. – user541686 Dec 16 '10 at 06:19
  • @sje397 I'm sure there aren't any #define in the source code. – m4design Dec 16 '10 at 06:21
  • It's bad because what you're seeing isn't what you're getting -- it's text that will be replaced, and you have no idea if it's an `int`, `long long`, etc. Furthermore, it has no scope or anything... see this link: http://stackoverflow.com/questions/1674032/static-const-vs-define-in-c – user541686 Dec 16 '10 at 06:23
  • instead of being sure, just try with #undef LEN, or use __len for example... uppercase is used for macros and defines – fazo Dec 16 '10 at 06:23
  • @Lambert: Apparently you don't know C. `const` variables are nearly useless in C. They certainly don't define constants. – R.. GitHub STOP HELPING ICE Dec 16 '10 at 06:24
  • @Lambert Ok; your edit made it clearer. Thanks – Michael Mrozek Dec 16 '10 at 06:24
  • @R: This is C++ too, though, right? – user541686 Dec 16 '10 at 06:25
  • 1
    All the #defines are global, that's why they are bad. One day you'll want to #define another LEN somewhere below in this unit. It's not a really big deal when all the #defines in one .cpp unit, but can still be annoying. – Sergei Tachenov Dec 16 '10 at 06:28

4 Answers4

10

You might have compiled your code using .c extension. MS Visual C doesn't support C99. In C89 the size of an array must be a constant expression. const qualified variables are not constants in C. They cannot be used at places where a real constant is required.

Also read this excellent post by AndreyT.

Try saving the file with .cpp extension.

Community
  • 1
  • 1
Karthik
  • 116
  • 1
  • 2
  • Works for me in gcc, no matter what dialect of C I specify. But I think you might be on to something as far as tweaking Visual Studio. – Jon Reid Dec 16 '10 at 06:25
  • 1
    @Jon : gcc supports C99 and Variable Length Arrays are part of C99, so the code works in gcc. The code is valid in C99 and C++. – Karthik Dec 16 '10 at 06:27
  • @Jon With `-ansi`, GCC gives `warning: ISO C90 forbids variable-size array ‘x’` – Josh Lee Dec 16 '10 at 06:27
2

You could also use

int main()
{
    enum { LEN = 5 };
    int x[LEN];
}
TmsKtel
  • 361
  • 3
  • 11
  • This works. Tested right now with VS2015. Language extensions disabled as well. The crappy thing is that Microsoft in their documentation uses a example that doesn't work https://msdn.microsoft.com/en-us/library/eff825eh(VS.71).aspx – John Leidegren Aug 06 '16 at 16:44
2

As per http://msdn.microsoft.com/en-us/library/3ffb821x.aspx, "Values declared as const that are initialized with constant expressions" are legal in array bounds, so this is valid C++ code.

Thus, that's either a compiler bug or something bizarre coming off a #define somewhere. As sje397's comment suggests, try some name other than LEN for the length? Also, is that actually your entire code, or are headers being #included as well?

Edit to add: Also, the fact that this is valid C++ code of course doesn't matter if you're compiling this as C, as others have noted.

Brooks Moses
  • 9,267
  • 2
  • 33
  • 57
  • It's more like a not implemented feature rather than a serious bug. I had the same problem when porting my code from G++ to some other compiler, I don't remember which one though. – Sergei Tachenov Dec 16 '10 at 06:34
  • I'd argue that in C++ it's a serious bug (it's pretty basic that a constant expression should in fact be a constant expression), while in C99 the bug would be a not-implemented-feature of variable-length arrays. But a fair point. – Brooks Moses Dec 16 '10 at 20:02
1

because in this case, I can do :

int main()
{
    const int LEN = 5;
    int* LENptr = (int*)(&LEN);
    *LENptr = 10;
    int x[LEN];
}

which const is only means read-only in this code, not compile-time constant

uray
  • 11,254
  • 13
  • 54
  • 74
  • 3
    This "sample" exhibits undefined behaviour so you can't infer anything about the language from its behaviour. – CB Bailey Dec 16 '10 at 06:25
  • You can write that code, and can perhaps compile it, but does casting away the constness of your pointer-target actually mean that it's legal C++ to then change its value? I don't think so. If I add `printf("%d\n", LEN);` to the end of that code, and compile it with g++ and run it, it prints 5, not 10. I'm almost surprised it doesn't segfault. – Brooks Moses Dec 16 '10 at 06:30
  • I just tried your code (for science :), but LEN never changed. So, maybe it is as Bailey said "undefined behaviour". – m4design Dec 16 '10 at 06:30
  • Of course, I realize the original poster didn't say whether this was C++ or C, and I just assumed from the C++ tag that it was C++ -- I didn't see the C tag. – Brooks Moses Dec 16 '10 at 06:34
  • It definitely will segfault on some platforms. That happened to me once. – Sergei Tachenov Dec 16 '10 at 06:36