views:

80

answers:

4

I'm trying to create a WCHAR:

LONG bufferSize = foo.bar() + 1;
WCHAR wszBaz[bufferSize];

The compiler issues an error:

error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0
error C2133: 'wszBaz' unknown size

What am I doing wrong?

UPDATE: I added const but it still gives the same error:

const LONG bufferSize = foo.bar() + 1;
WCHAR wszBaz[bufferSize];
+3  A: 

The size of an array is a constant expression. bufferSize is not a constant expression.

Use a vector: std::vector<WCHAR> wszBaz(bufferSize);, or a std::wstring.

GMan
A: 

You are trying to create a variable sized array on the stack.

The best way to do this is to create the array on the heap as follows:

WCHAR* pszBaz = new WCHAR[bufferSize];

You then need to remember to delete[] it when you have finished with it.

Even easier though is just to use std::wstring ...

Goz
It's totally illegal to create a variable sized array on the stack? Is that because someone could potentially create an array larger than the stack frame?
Rosarch
I'd say the best way to do any array allocation from the heap is a `vector`. :) @Rosarch: Yes, it's totally illegal. And yes, that's a potential issue. C99 supports variable-length arrays (VLA's), C++ does not.
GMan
@GMan ... arguably I'd suggest that std::wstring is a far simpler way than using a vector. Use the right container and all that ;)
Goz
@Goz: A `vector` gives you a legal interface to write to the contained elements as a contiguous array which more closely matches the original code. To answer whether a `std::basic_string` has a sufficient interface for the asker would need more context.
Charles Bailey
@Rosarch: There's not a fundamental reason why it's illegal, but it was illegal in C90 and stays illegal in C++. C99 has at least something similar, but in C++, you'd be expected to use a vector rather than a variable-length array.
David Thornley
A: 

Why not just use std::wstring?

If you need to make sure it has a certain number of bytes, you can either do that when you construct it:

std::wstring baz(bufferSize, ' ');

or you can use the reserve method:

std::wstring baz;
baz.reserver(bufferSize);
R Samuel Klatchko
A: 

Array sizes must be constant expression:

const int foo = 10;
WCHAR array1[123]; // ok - 123 is a constant expression
WCHAR array2[foo + 10]; // ok too - the expression is constant
WCHAR array3[bar(123)]; // not ok - it may evaluate to the same thing every time, but function calls aren't seen as constant.

Note that const does not make something a const expression. A const expression is something that is constant at compile time. The compiler is smart enough to figure out that something like 5+5 is a const expression, but isn't smart enough to figure out that foo(5,5) is a const expression -- even if foo(x,y) just returns x+y.

In the next C++ standard (C++0x), you will be able to define functions as const-expressions.

Peter Alexander
Right, and I marked it as `CONST long`, but it still doesn't work.
Rosarch
@Rosarch: That just means the variable is not mutable, not that it's a constant expression. It needs to be known at compile-time.
GMan