如何解释 C 预处理器输出中的#前缀行?
How to interpret #-prefixed lines in C preprocessor output?
下面是hello.c的代码:
#include <stdio.h>
int
main (void)
{
printf ("Hello, world!\n");
return 0;
}
我使用命令 gcc -E hello.c
对其进行预处理,得到以下输出:
# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "hello.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 375 "/usr/include/features.h" 3 4
# 1 "/usr/include/sys/cdefs.h" 1 3 4
# 392 "/usr/include/sys/cdefs.h" 3 4
# 1 "/usr/include/bits/wordsize.h" 1 3 4
# 393 "/usr/include/sys/cdefs.h" 2 3 4
# 376 "/usr/include/features.h" 2 3 4
# 399 "/usr/include/features.h" 3 4
# 1 "/usr/include/gnu/stubs.h" 1 3 4
# 10 "/usr/include/gnu/stubs.h" 3 4
# 1 "/usr/include/gnu/stubs-64.h" 1 3 4
# 11 "/usr/include/gnu/stubs.h" 2 3 4
# 400 "/usr/include/features.h" 2 3 4
# 28 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4
# 212 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 3 4
typedef long unsigned int size_t;
# 34 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/bits/types.h" 1 3 4
# 27 "/usr/include/bits/types.h" 3 4
# 1 "/usr/include/bits/wordsize.h" 1 3 4
# 28 "/usr/include/bits/types.h" 2 3 4
typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
typedef unsigned long int __u_long;
typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t;
typedef signed long int __int64_t;
typedef unsigned long int __uint64_t;
////I omitted a lot in the following.
我知道这些信息可用于调试符号。但是我想知道每个FIELD的含义。但是,如果您能够回答以下问题,您的回答也将被接受。
# 1 "<built-in>" and # 1 "<command-line>"
是什么意思?为什么它给了我完全不相关的内置和命令行消息?
#1 "/usr/include/stdc-predef.h" 1 3 4
是什么意思? 1 3 4 是什么意思?
谢谢。请注意,我知道预处理器将包含头文件。我想知道预处理输出的每个FIELD的含义。
预处理器输出的字段记录在 9 Preprocessor Output
GNU cpp 手册。
字段是:
# linenum filename [flags]
...
这样的一行意味着后面的内容(...
)起源于行
文件 filename
中的编号 linenum
。可选的 flags
是:-
‘1’
This indicates the start of a new file.
‘2’
This indicates returning to a file (after having included another file).
‘3’
This indicates that the following text comes from a system header file, so certain warnings should be suppressed.
‘4’
This indicates that the following text should be treated as being wrapped in an implicit extern "C" block.
您看到嵌套来自 #include
指令,例如
# 1 "hello.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 375 "/usr/include/features.h" 3 4
# 1 "/usr/include/sys/cdefs.h" 1 3 4
...
告诉我们:
- 在
"hello.c"
的第 1 行开始一个新文件 "/usr/include/stdio.h"
,
- 在第 27 行开始另一个新文件
"/usr/include/features.h"
- 在第 375 行开始另一个新文件
"/usr/include/sys/cdefs.h"
- ...
读起来不容易
特殊的“文件名”<built-in>
和 <command-line>
总是会出现
在类似于以下的上下文中:-
# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "hello.c"
在任何文件的预处理输出的顶部。详细信息可能因 GCC 版本而异。
如您所料,<built-in>
和 <command-line>
不是真实文件。他们
是 non-file 需要以某种方式表示的预处理器标记的来源
在输出格式中,因此它们被视为 就好像 它们是文件一样。叫他们 pseudo-files.
<built-in>
是包含编译器的 built-in 宏的 pseudo-file
定义。要查看此 pseudo-file 的内容,请浏览至
GCC dump preprocessor defines.
<command-line>
当然是预处理器(通常是 GCC)命令行,
被视为宏定义的来源(可能 un-definitions),例如
gcc ... -DFOO=1 -UBAR ...
所以你的例子:
# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "hello.c"
# 1 "/usr/include/stdio.h" 1 3 4
...
代表这个过程:
- 开始阅读
hello.c
,然后
- 立即读取built-in宏pseudo-file,然后
- 立即阅读命令行pseudo-file,然后
- 立即读取pre-defined宏文件
/usr/include/stdc-predef.h
好像它是-include /usr/include/stdc-predef.h
在命令行上pre-included,然后
- 继续阅读命令行pseudo-file,然后
- 继续阅读
hello.c
,然后
- 开始阅读
/usr/include/stdio.h
...
下面是hello.c的代码:
#include <stdio.h>
int
main (void)
{
printf ("Hello, world!\n");
return 0;
}
我使用命令 gcc -E hello.c
对其进行预处理,得到以下输出:
# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "hello.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 375 "/usr/include/features.h" 3 4
# 1 "/usr/include/sys/cdefs.h" 1 3 4
# 392 "/usr/include/sys/cdefs.h" 3 4
# 1 "/usr/include/bits/wordsize.h" 1 3 4
# 393 "/usr/include/sys/cdefs.h" 2 3 4
# 376 "/usr/include/features.h" 2 3 4
# 399 "/usr/include/features.h" 3 4
# 1 "/usr/include/gnu/stubs.h" 1 3 4
# 10 "/usr/include/gnu/stubs.h" 3 4
# 1 "/usr/include/gnu/stubs-64.h" 1 3 4
# 11 "/usr/include/gnu/stubs.h" 2 3 4
# 400 "/usr/include/features.h" 2 3 4
# 28 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 1 3 4
# 212 "/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h" 3 4
typedef long unsigned int size_t;
# 34 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/bits/types.h" 1 3 4
# 27 "/usr/include/bits/types.h" 3 4
# 1 "/usr/include/bits/wordsize.h" 1 3 4
# 28 "/usr/include/bits/types.h" 2 3 4
typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
typedef unsigned long int __u_long;
typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t;
typedef signed long int __int64_t;
typedef unsigned long int __uint64_t;
////I omitted a lot in the following.
我知道这些信息可用于调试符号。但是我想知道每个FIELD的含义。但是,如果您能够回答以下问题,您的回答也将被接受。
# 1 "<built-in>" and # 1 "<command-line>"
是什么意思?为什么它给了我完全不相关的内置和命令行消息?#1 "/usr/include/stdc-predef.h" 1 3 4
是什么意思? 1 3 4 是什么意思?
谢谢。请注意,我知道预处理器将包含头文件。我想知道预处理输出的每个FIELD的含义。
预处理器输出的字段记录在 9 Preprocessor Output GNU cpp 手册。
字段是:
# linenum filename [flags]
...
这样的一行意味着后面的内容(...
)起源于行
文件 filename
中的编号 linenum
。可选的 flags
是:-
‘1’
This indicates the start of a new file.
‘2’
This indicates returning to a file (after having included another file).
‘3’
This indicates that the following text comes from a system header file, so certain warnings should be suppressed.
‘4’
This indicates that the following text should be treated as being wrapped in an implicit extern "C" block.
您看到嵌套来自 #include
指令,例如
# 1 "hello.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 375 "/usr/include/features.h" 3 4
# 1 "/usr/include/sys/cdefs.h" 1 3 4
...
告诉我们:
- 在
"hello.c"
的第 1 行开始一个新文件"/usr/include/stdio.h"
, - 在第 27 行开始另一个新文件
"/usr/include/features.h"
- 在第 375 行开始另一个新文件
"/usr/include/sys/cdefs.h"
- ...
读起来不容易
特殊的“文件名”<built-in>
和 <command-line>
总是会出现
在类似于以下的上下文中:-
# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "hello.c"
在任何文件的预处理输出的顶部。详细信息可能因 GCC 版本而异。
如您所料,<built-in>
和 <command-line>
不是真实文件。他们
是 non-file 需要以某种方式表示的预处理器标记的来源
在输出格式中,因此它们被视为 就好像 它们是文件一样。叫他们 pseudo-files.
<built-in>
是包含编译器的 built-in 宏的 pseudo-file
定义。要查看此 pseudo-file 的内容,请浏览至
GCC dump preprocessor defines.
<command-line>
当然是预处理器(通常是 GCC)命令行,
被视为宏定义的来源(可能 un-definitions),例如
gcc ... -DFOO=1 -UBAR ...
所以你的例子:
# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "hello.c"
# 1 "/usr/include/stdio.h" 1 3 4
...
代表这个过程:
- 开始阅读
hello.c
,然后 - 立即读取built-in宏pseudo-file,然后
- 立即阅读命令行pseudo-file,然后
- 立即读取pre-defined宏文件
/usr/include/stdc-predef.h
好像它是-include /usr/include/stdc-predef.h
在命令行上pre-included,然后 - 继续阅读命令行pseudo-file,然后
- 继续阅读
hello.c
,然后 - 开始阅读
/usr/include/stdio.h
...