const variables may not be used in a constant expression?

2.7k views Asked by At

Why is this C code illegal in Visual Studio 2013 Ultimate?

const unsigned int x = 64;
char resultBufNative[x+1];

It gives error C2057: expected constant expression.


Original question

I'm completely baffled by this one.

Relevant function:

jstring Java_com_nabto_api_NabtoCApiWrapper_nabtoGetSessionToken(JNIEnv* env, jclass thiz, jobject sessionObj)
{
    const size_t size = 64;
    char resultBufNative[size+1];

    size_t resultLen;

    //Get the session
    nabto_handle_t session;
    session = (nabto_handle_t) (*env)->GetDirectBufferAddress(env, sessionObj);

    nabto_status_t nabtoStatus = nabtoGetSessionToken(session, resultBufNative, size, &resultLen);

    if (nabtoStatus == NABTO_OK && resultLen <= size) {
        // Terminate char array, convert to java string, free buffer and return result
        resultBufNative[resultLen] = 0;
        jstring result = (*env)->NewStringUTF(env, resultBufNative);
        //nabtoFree(resultBufNative);
        return result;
    }
    else {
        return NULL;
    }
}

Error message: error C2057: expected constant expression

On line char resultBufNative[size+1];

To me, that makes the relevant code as such:

    const size_t size = 64;
    char resultBufNative[size+1];

And apparently, const size_t + 1 is not a constant expression.

There are no defines or macros size dicking about (replacing it with xyzabc gives the same error). size_t is defined as typedef unsigned int __w64 size_t when I mouseover size_t in my IDE (Visual Studio Ultimate 2013).

After the C2057 expected constant expression error, the compiler gives 2 more errors:

C24166: cannot allocate array of size 0
C2133: 'resultBufNative': unknown size

For the same line of code. Naturally, these are because it doesn't know what size + 1 is, so it becomes 0.

Using

    constexpr const size_t size = 64;
    char resultBufNative[size+1];

Gives error C2065: 'constexpr' : undeclared identifier.

Using

    const size_t size = 65;
    char resultBufNative[size];

Gives error C2057: expected constant expression.

Using

    static const size_t size = 64;
    char resultBufNative[size+1];

Gives error C2057: expected constant expression.

Using

    const unsigned int x = 64;
    char resultBufNative[x+1];

Gives error C2057: expected constant expression.

I guess what I want to do is not supported.

2

There are 2 answers

11
P.P On BEST ANSWER

In C89 mode, the array size must be a compile time constant but size is not one. const keyword means read only, not compile time constant (this is different in C++). So you have few options here:

1) Compile in C99 mode which supports VLAs.

2) Use fixed size arrays:

   char resultBufNative[64+1];

3) Use

#define size 64

which is basically same as option (2) except preprocessor does that replacement for you.

4) Use enum as suggested by bluepixy, which is a compile time constant unlike const.

0
tofutim On

An updated solution is to compile as C++ using /Tp in Visual Studio 2015. While not perfect, the C++ compiler supports a large subset of C99.