9

为什么这个 C 代码在 Visual Studio 2013 Ultimate 中是非法的?

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

它给error C2057: expected constant expression.


原始问题

我完全被这个迷惑了。

相关功能:

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 C2057: expected constant expression

在线的char resultBufNative[size+1];

对我来说,这使得相关代码如下:

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

显然,const size_t + 1不是一个常量表达式。

没有定义或宏size在讨论(用 xyzabc 替换它会产生相同的错误)。size_t定义为typedef unsigned int __w64 size_t当我size_t在 IDE(Visual Studio Ultimate 2013)中鼠标悬停时。

在 C2057 预期的常量表达式错误之后,编译器又给出了 2 个错误:

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

对于同一行代码。自然,这些是因为它不知道是什么size + 1,所以它变成了0。

使用

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

error C2065: 'constexpr' : undeclared identifier.

使用

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

error C2057: expected constant expression.

使用

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

error C2057: expected constant expression.

使用

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

error C2057: expected constant expression.

我想我想做的事情不受支持。

4

2 回答 2

6

在 C89 模式下,数组大小必须是编译时间常数,但size不是一。const关键字表示只读,而不是编译时间常数(这在 C++ 中有所不同)。所以你在这里有几个选择:

1) 在支持 VLA 的 C99 模式下编译。

2)使用固定大小的数组:

   char resultBufNative[64+1];

3) 使用

#define size 64

这与选项 (2) 基本相同,只是预处理器会为您进行替换。

4)enum按照 bluepixy 的建议使用,这是一个编译时间常数,不像const.

于 2014-11-12T10:32:43.193 回答
-1

一个更新的解决方案是在 Visual Studio 2015 中使用 /Tp 编译为 C++。虽然不完美,但 C++ 编译器支持 C99 的大部分子集。

于 2015-12-01T18:11:44.647 回答