【发布时间】:2011-04-15 18:44:10
【问题描述】:
此代码无法在 GCC 版本 4.3.2 (Debian 4.3.2-1.1) 上为我编译
main() {
int unix;
}
我检查了 C 关键字列表,“unix”不是其中之一。
为什么会出现以下错误?
unix.c:2: error: expected identifier or ‘(’ before numeric constant
【问题讨论】:
此代码无法在 GCC 版本 4.3.2 (Debian 4.3.2-1.1) 上为我编译
main() {
int unix;
}
我检查了 C 关键字列表,“unix”不是其中之一。
为什么会出现以下错误?
unix.c:2: error: expected identifier or ‘(’ before numeric constant
【问题讨论】:
unix 不是标准保留的标识符。
如果您使用-std=c89 或-std=c99 进行编译,gcc 编译器将按照您的预期接受程序。
来自 gcc 手册 (https://gcc.gnu.org/onlinedocs/cpp/System-specific-Predefined-Macros.html),重点是我的。
... 但是, 历史上特定于系统的宏 有没有特殊前缀的名字; 例如,通常会发现 unix 定义在 Unix 系统上。对所有人 这样的宏,GCC 提供了一个并行 添加两个下划线的宏 开始和结束。如果 unix 是 已定义,__unix__ 也将被定义。 永远不会超过两个 下划线; _mips 的平行是 __mips__。
【讨论】:
这不是关键字。
这是一个用于识别系统类型的预定义宏。在 Unix 和类似 Unix 的系统上,它被定义为 1。
要禁用此功能,请使用 -ansi 选项:
在 C 模式下,这相当于 -std=c89。在 C++ 模式下,相当于 -std=c++98。 这将关闭与 ISO C90(编译 C 代码时)或标准 C++(编译 C++ 代码时)不兼容的 GCC 的某些功能,例如“asm”和“typeof”关键字,以及 预定义的宏,例如作为 "unix" 和 "vax" 标识您正在使用的系统类型。它还启用了不受欢迎且很少使用的 ISO trigraph 功能。对于 C 编译器,它禁止识别 C++ 样式 // cmets 以及“inline”关键字。
【讨论】:
unix 是 gcc 中预处理器使用的定义之一 获取 defs 使用列表
gcc -dM -E -x c /dev/null
(-dM 告诉 gcc 调试 defs -E 告诉它在预处理后停止,-xc /dev/null 告诉他假装 /dev/null 是 ac 文件)
【讨论】:
echo | gcc -E -dD -
通过预处理器运行您的代码以找出编译器实际看到的内容:
gcc -E unix.c
然后看看你的变量unix是否被预处理器保留或转换。
【讨论】:
回答您的问题,unix 不是 C 中的保留字。
但是,符号unix 很可能是由预处理器定义的,要么是因为您包含了头文件,要么是因为编译器定义了它。
【讨论】:
我将对此进行疯狂的尝试,并猜测 gcc 在 UNIX 系统上有效地将 unix 定义为 1。
试试
main(){
printf("%d", unix);
}
看看你会得到什么。
【讨论】:
gcc 倾向于定义此宏。