我一直在调试一个奇怪的编译错误,该错误是我进入代码内部的,最终我发现如果{{1},某些变量名(任何类型)不能使用前缀si_
。 }。
这是一个非常简单的源代码示例,它再现了该问题:
<signal.h>
如果我尝试使用GNU C编译器#include <signal.h>
int main(void)
{
int si_value = 0;
return 0;
}
进行编译,则会出现以下错误:
gcc
尽管如此,如果我使用其他名称,例如> gcc example.c
In file included from /usr/include/signal.h:57:0,
from example.c:2:
example.c: In function ‘main’:
example.c:6:9: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token
int si_value = 0;
^
example.c:6:9: error: expected expression before ‘.’ token
,则不会出现错误。作为参考,我在Ubuntu Mate 18.04.1 LTS上使用GCC v7.3.0。使用si_value2
会遇到相同的问题。
我想这种行为是由于g++
标头中的一些宏定义引起的,但是在简要地经过它之后,我似乎找不到任何真正相关的东西。
老实说,我可以使用其他名称来修复它。但是,我担心的是:我将来如何优雅地避免此类问题?
更新:作为@ F.X。建议使用<signal.h>
表示变量名已扩展(因此,出现错误):
gcc -E example.c
答案 0 :(得分:23)
<signal.h>
实际上并不能阻止在变量上使用si_
作为前缀。但是,POSIX规范指出此前缀是保留的,以便允许它声明的头文件和库函数使用这些名称,而不必担心它们会与您自己的变量冲突。
因此,这里发生的是si_value
在头文件中以某种方式定义,也许定义为宏或typedef,并且您尝试使用相同名称的尝试与此冲突。如果您使用si_vy1ghad563nvy43wd
可能会起作用,但是理论上标头可以使用该名称(认为与应用程序程序员使用的任何内容都不太可能冲突)。
C没有真正的名称空间,因此将这样的命名约定用作简单的替换。
答案 1 :(得分:12)
我将来如何优雅地避免此类问题?
您检查一些documentation中正在使用的标题,并避免记录为保留的名称。