C++ 为什么<;信号h>;防止使用;"是";作为某些变量名称的前缀?
我一直在调试代码中出现的一个奇怪的编译错误,结果发现如果包含C++ 为什么<;信号h>;防止使用;"是";作为某些变量名称的前缀?,c++,c,linux,C++,C,Linux,我一直在调试代码中出现的一个奇怪的编译错误,结果发现如果包含,我就不能对某些变量名(任何类型)使用前缀si\ucode> 下面是一个非常简单的源代码示例,再现了这个问题: #include <signal.h> int main(void) { int si_value = 0; return 0; } 尽管如此,如果我使用另一个名称,例如si_value2,则不会显示错误。作为参考,我在Ubuntu Mate 18.04.1 LTS上使用GCC v7.3.0。
,我就不能对某些变量名(任何类型)使用前缀si\ucode>
下面是一个非常简单的源代码示例,再现了这个问题:
#include <signal.h>
int main(void)
{
int si_value = 0;
return 0;
}
尽管如此,如果我使用另一个名称,例如si_value2
,则不会显示错误。作为参考,我在Ubuntu Mate 18.04.1 LTS上使用GCC v7.3.0。在g++
中也观察到同样的问题
我认为这种行为是由于
标题中的一些宏定义造成的,但在简要地查看之后,我似乎找不到任何真正相关的内容
老实说,我可以用另一个名字来修复它。然而,我担心的是:我今后如何优雅地避免此类问题?
更新:正如@F.X.所建议的,使用gcc-E示例。c
显示变量名已展开(因此出现错误):
我怎样才能在将来优雅地避免此类问题
您可以检查一些正在使用的标题,并避免记录为保留的名称。
实际上并不会阻止在变量上使用si\uu
作为前缀。但是,POSIX规范声明保留该前缀,以便允许它声明的头和库函数使用这些名称,而不必担心它们会与您自己的变量冲突
所以这里发生的事情是,si_value
在头文件中以某种方式定义,可能是作为宏或typedef,您尝试使用相同的名称与此冲突。如果您使用了si_vy1ghad563nvy43wd
,它可能会起作用,但理论上头部可以使用该名称(认为它不太可能与应用程序程序员使用的任何名称冲突)
C没有真正的名称空间,所以像这样的命名约定被用作一个简单的替代品。你能看看gcc-E
(就在预处理器之后)的输出吗?它可能会提示您出了什么问题。它只是名称si_值
?闻起来好像宏被替换到了代码中。类似于si_vy1ghad563nvy43wd
的东西呢?@alterigel抱歉,si_vy1ghad563nvy43wd
也是一个保留关键字。@AndrewHenle好吧,这是一个笑话。它在哪里说si_value
是一个保留名称?我所看到的只是在siginfo\u t
结构中对该名称字段的引用,但这完全不是一回事?@unwind 2.2.2namespace@Jean-弗朗索瓦·法布可能也用同样的方式保留了一个\u t
suffix@Jean-Françoisfare——它之所以保留是因为POSIX(搜索siçuz)。@SRG不用担心;你的投票,你的判断,这都是出于设计。标识符不是以“\uuuuuuuuuuuuu”开头的吗?它不能用它来代替吗?或者这是其他的东西?我认为这实际上是一个POSIX的东西,而\uuu
是一个C的东西。因此,POSIX试图避免保留给C实现的名称。但signal.h
不是标准头吗?C11保留以SIG
开头,后跟大写字母的名称,或SIG
后跟大写字母(C11)。当包含
时,POSIX会保留更多的符号前缀-。C标准保留了前导的\uuuu
供实现(C11)使用。阅读并注意避免冲突。或者在它们出现时修复。@Kevin:The
头既是标准的C头,也是标准的POSIX头。由于在调用GCC时没有指定-std=c11
或类似项,因此它启用了所有GNU扩展,其中包括POSIX函数和符号。如果指定了-std=c11
,则可能需要在编译器命令行上编写-dxopen\u SOURCE=700
,或者在头或代码中编写类似的#define
(我建议在头中执行此操作,十年前在代码中使用过一次,并且此后花费了相当长的时间撤消它)。
> 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
...
int
# 6 "example.c" 3 4
_sifields._rt.si_sigval
# 6 "example.c"
= 0;
...