4

我只在 MSVC 中收到一个奇怪的C代码编译错误。更确切地说:

错误 C2143:语法错误:缺少“;” 在“类型”之前

C2143 是一个相当普遍的错误,围绕它有无数关于 SO 的问题,但到目前为止似乎没有一个问题适用。最接近的可以在这里找到,并强调在块的开头声明变量的重要性,这似乎在这里得到了尊重。

这是一个示例代码:

#define       NB_LL 6
typedef struct { long long ll[NB_LL ]; } stateSpace_t;
#define ALLOCATE_ONSTACK(stateName)  stateSpace_t stateName##_s; void* stateName = (void*) &(stateName##_s);

以下代码运行良好:

void f1()
{
    ALLOCATE_ONSTACK(state1);
    /* do something */
}

这个没有:

void f2()
{
    ALLOCATE_ONSTACK(state1);
    ALLOCATE_ONSTACK(state2);   // <--- error C2143: syntax error : missing ';' before 'type'
    /* do something */
}

第二个代码适用于 GCC,因此问题似乎仅限于 MSVC。我的理解是宏ALLOCATE_ONSTACK()只做变量声明和初始化,所以它似乎尊重C语法。

是吗?

4

2 回答 2

7

好的,这个相当复杂。

看着那(这

#define ALLOCATE_ONSTACK(stateName)

它以一个;字符结束。

现在看看你的代码:

ALLOCATE_ONSTACK(state1);

它也以一个';'字符结尾。这意味着,在此特定行上,您有 2 个以下';'字符。

由于 MSVC 不是 C99,它要求所有声明都在块的开头完成。由于您有两个';'字符相互跟随,因此它的作用就像声明区域已结束。因此,当您在中声明其他变量时:

ALLOCATE_ONSTACK(state2);

然后失败,语法错误。

GCC 没有这样的问题,因为它是 C99。

删除';'宏末尾或源代码中的字符。只有一个是必需的。不确定哪种解决方案更好...

[编辑]:正如评论和其他答案中所建议的,从宏中删除分号看起来是更好的解决方案。

于 2013-05-31T03:15:14.400 回答
4

在 ALLOCATE_ONSTACK 宏定义的末尾以及调用的末尾都有一个分号。这意味着您在每次宏展开后实际上都有一个空语句。因此,第二个扩展不在块的开头。

传统上,C 要求所有声明都出现在第一个非声明语句之前的块中。gcc 放宽了这个要求,所以错误不会发生。

我建议重写你的宏定义而不使用尾随分号。

编辑:打一拳。

于 2013-05-31T03:14:37.387 回答