gcc 中将非保留标识符作为内置宏的原因是什么?
今天,我偶然发现了一个相当有趣的编译器错误:
int main() {
int const unix = 0; // error-line
return unix;
}
使用 gcc 4.3.2 给出以下消息(是的,古老的......):
error: expected unqualified-id before numeric constant
这绝对是相当令人困惑的。
幸运的是,clang (3.0) 有点帮助(像往常一样):
error: expected unqualified-id
int const unix = 0
^
<built-in>:127:14: note: expanded from:
#define unix 1
^
我当然没想到 unix
既不是用大写写的,也不是以下划线开头的,它是一个宏,尤其是一个内置的-合而为一。
我检查了 gcc 中的预定义宏,有 2 个(在我的平台上)使用“未保留”符号:
$ g++ -E -dM - < /dev/null | grep -v _
#define unix 1
#define linux 1
所有其他都是带有前导下划线的“行为良好”宏,使用传统的保留标识符,示例:(
#define __linux 1
#define __linux__ 1
#define __gnu_linux__ 1
#define __unix__ 1
#define __unix 1
#define __CHAR_BIT__ 8
#define __x86_64 1
#define __amd64 1
#define _LP64 1
这是一团糟,似乎没有任何特定的顺序...)
此外,还有很多“相似”的符号,所以我猜测存在向后兼容性的问题...
那么,unix
在哪里和linux
宏来自于?
Today I stumbled upon a rather interesting compiler error:
int main() {
int const unix = 0; // error-line
return unix;
}
Gives the following message with gcc 4.3.2 (yes, ancient...):
error: expected unqualified-id before numeric constant
which is definitely quite confusing.
Fortunately, clang (3.0) is a little more helpful (as usual):
error: expected unqualified-id
int const unix = 0
^
<built-in>:127:14: note: expanded from:
#define unix 1
^
I certainly did not expect unix
, which is neither written in upper-case nor begin with underscore to be a macro, especially a built-in one.
I checked the predefined macros in gcc and there are 2 (on my platform) that use "unreserved" symbols:
$ g++ -E -dM - < /dev/null | grep -v _
#define unix 1
#define linux 1
All the others are "well-behaved" macros with leading underscores, using the traditional reserved identifiers, sample:
#define __linux 1
#define __linux__ 1
#define __gnu_linux__ 1
#define __unix__ 1
#define __unix 1
#define __CHAR_BIT__ 8
#define __x86_64 1
#define __amd64 1
#define _LP64 1
(it's a mess and there does not seem to be any particular order...)
Furthermore, there are lots of "similar" symbols, so I guess there is an issue of backward compatibility...
So, where do the unix
and linux
macros come from ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
默认情况下,gcc 并不完全符合任何 C 标准。
使用
-ansi
、-std=c99
或-std=c1x
调用它,并且unix
不会预定义的。 (-std=c1x
可能会成为在未来更新的 gcc 版本中成为-std=c11
。)有点令人困惑的是,这是在 GNU 预处理器的单独手册中记录的,而不是在 gcc 手册中。
引用 GNU 预处理器文档(
info cpp
,版本 4.5):当前版本的手册是 这里。
gcc does not fully conform to any C standard by default.
Invoke it with
-ansi
,-std=c99
, or-std=c1x
andunix
won't be predefined. (-std=c1x
will probably becomebecame-std=c11
in afuturemore recent gcc release.)It's a bit confusing that this is documented in the separate manual for the GNU preprocessor, not in the gcc manual.
Quoting the GNU preprocessor documentation (
info cpp
, version 4.5):The current version of the manual is here.