
在 GCC 预处理器的输出(.i或 .ii文件)中,行标记(line marker)的通用格式为:
# linenum filename [flags]
其中 linenum是源代码中的行号,filename是源文件路径,后面的 flags 是一个或多个用空格分隔的数字,每个数字代表一种属性。这些数字的含义如下:
| 数字 | 含义 | 说明 |
|---|---|---|
| 1 | 开始一个新文件(Start of new file) | 表示从此处起进入一个新的包含文件(#include引入的文件)。 |
| 2 | 返回到上一个文件(Return to previous file) | 表示从包含文件返回,继续处理上一级文件。 |
| 3 | 此文件来自系统头文件(System header) | 标记该文件是系统头文件(如 /usr/include/下的文件),编译器会对其中的警告进行抑制。 |
| 4 | 视为 C++ 的 extern "C"块(Extern "C" block) | 表示该文件的内容应被当作 extern "C"包裹,用于 C/C++ 混合编译时避免名字修饰。 |
在The C Preprocessor中,对行标记的解释如下:
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.
如下面代码中:
# 1 "kernel/FreeRTOS-orig/Source/include/FreeRTOS.h" 1
# 33 "kernel/FreeRTOS-orig/Source/include/FreeRTOS.h"
# 1 "/rtos/lichee/rtos/tools/riscv64-elf-x86_64-20201104/lib/gcc/riscv64-unknown-elf/8.4.0/include/stddef.h" 1 3 4
# 149 "rtos/lichee/rtos/tools/riscv64-elf-x86_64-20201104/lib/gcc/riscv64-unknown-elf/8.4.0/include/stddef.h" 3 4
这些标志可以组合出现,GCC 会在行标记后依次列出所有适用的标志。例如:
# 1 "FreeRTOS.h" 1
表示进入 FreeRTOS.h 文件,且是新文件的开始(flag=1)。# 33 "FreeRTOS.h"
没有 flag,表示仍在 FreeRTOS.h 中,第 33 行,无特殊属性。# 1 "stddef.h" 1 3 4
进入 stddef.h,且它既是新文件(1)、又是系统头文件(3)、还相当于extern "C"块(4)。# 149 "stddef.h" 3 4
仍在 stddef.h 中,第 149 行,此时不再是新文件开始(没有 1),但仍保留系统头(3)和 extern "C"(4)属性。
示例说明1
- 标志 2 通常出现在文件包含结束处,例如
# 123 "main.c" 2表示从包含文件返回 main.c 的第 123 行。 - 如果没有任何标志,则默认该行是普通源代码行。
- 这些行标记主要用于帮助调试器(如 GDB)定位源码位置,同时也影响编译器的诊断行为(如对系统头文件少报 warning)。
在以上例子中,# 1 "stddef.h" 1 3 4意味着:这是一个新包含的系统头文件,并且其内容应当被当作 extern "C"来处理;而后续的 # 149 "stddef.h" 3 4则表示在同一文件中继续,但不再是文件开头(去掉 flag 1)。
示例说明2
以下面代码为例,进行逐行的补充说明
# 10 "drivers/rtos-hal/include/osal/hal_osal.h" 2
# 1 "drivers/rtos-hal/include/osal/hal_status.h" 1
# 4 "drivers/rtos-hal/include/osal/hal_status.h"
# 12 "drivers/rtos-hal/include/osal/hal_osal.h" 2
# 1 "drivers/rtos-hal/include/osal/hal_atomic.h" 1
# 10 "drivers/rtos-hal/include/osal/hal_osal.h" 2
- 含义:返回到文件
hal_osal.h的第 10 行。 - 标志 2 表示“返回到上一个文件”,即刚刚结束了一个被包含文件的处理,现在继续处理
hal_osal.h中第 10 行及之后的代码。 - 这一行通常出现在某个
#include指令对应的被包含文件全部展开之后。此处应是前一个包含(例如系统头文件)处理完毕后的返回点。
(空行)
- 预处理输出中保留的空行,对应原始源文件中的空行或无关紧要的空白。
# 1 "drivers/rtos-hal/include/osal/hal_status.h" 1
- 含义:开始处理一个新文件
hal_status.h,行号为 1。 - 标志 1 表示“新文件开始”,即遇到
#include "hal_status.h"指令后,预处理器切换到此文件。 - 这表明
hal_osal.h中包含了对hal_status.h的引用,且该引用位于hal_osal.h的第 9 行(因为返回后是第 10 行)。
# 4 "drivers/rtos-hal/include/osal/hal_status.h"
- 含义:仍在
hal_status.h文件中,当前处理到第 4 行。 - 此行没有标志(或标志为 0),表示普通源代码行,无特殊属性。
# 12 "drivers/rtos-hal/include/osal/hal_osal.h" 2
- 含义:从
hal_status.h返回hal_osal.h的第 12 行。 - 标志 2 再次表示返回上一级文件。
- 注意返回的行号是 12,而非 10,说明在
hal_osal.h中,#include "hal_status.h"指令位于第 9 行,返回后是第 10 行;随后第 10~11 行可能包含其他代码(如空行、注释或其他预处理指令),然后第 12 行是下一个#include指令的位置。
# 1 "drivers/rtos-hal/include/osal/hal_atomic.h" 1
- 含义:开始处理新文件
hal_atomic.h,行号为 1。 - 标志 1 表示新文件开始,即
hal_osal.h在第 12 行通过#include "hal_atomic.h"引入了此文件。
包含顺序
hal_osal.h首先被hal_atomic.c包含(之前行标记可见)。hal_osal.h在处理过程中,先包含系统头文件(未在此片段中完全展示),然后返回至第 10 行。- 接着包含
hal_status.h(第 9 行的#include),处理完后返回hal_osal.h第 12 行。 - 最后包含
hal_atomic.h(第 12 行的#include),开始处理该文件。
518

被折叠的 条评论
为什么被折叠?



