我在MSVC中的 C 代码中遇到奇怪的编译错误。更确切地说:
错误C2143:语法错误:缺少';'在'type'之前
C2143是一个相当普遍的错误,围绕它有无数的问题,但到目前为止它们似乎都没有。 最接近的一个可以是found here,并强调在块的开头声明变量的重要性,这似乎在这里得到了尊重。
以下是示例代码:
#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 语法。
答案 0 :(得分:6)
好的,这个很复杂。
看看
#define ALLOCATE_ONSTACK(stateName)
以;
字符结尾。
现在看看你的代码:
ALLOCATE_ONSTACK(state1);
它也以';'
字符结尾。这意味着,在此特定行上,您有2个';'
个字符。
由于MSVC不是C99,它要求所有声明都在块的开头完成。由于您有两个';'
个字符,因此它就像声明区域已结束一样。因此,当您在:
ALLOCATE_ONSTACK(state2);
然后失败,语法错误。
GCC没有这样的问题,因为它是C99。
删除宏末尾或源代码中的';'
字符。只需要一个。不确定哪种解决方案更好......
[编辑]:正如评论和其他答案中所建议的那样,从宏中删除分号看起来是更好的解决方案。
答案 1 :(得分:3)
您在ALLOCATE_ONSTACK宏定义的末尾以及调用结束时都有一个分号。这意味着您在每次宏扩展后都有效地使用null语句。因此,第二次扩展不是在块的开头。
经典地,C要求所有声明都在第一个非声明语句之前的块中发生。 gcc放宽了这个要求,因此不会发生错误。
我建议重写你的宏定义,而不要使用尾随分号。
编辑:击败拳头。