目录
生成预处理文件的的命令
预处理做了什么
实验
---------------------------------------------------------------------------------------------------------------------------------
本篇文章主要是带着大家一起看看预处理阶段编译器都做了些什么
---------------------------------------------------------------------------------------------------------------------------------
预处理_哔哩哔哩_bilibili
生成预处理文件的的命令
gcc -E test.c -o test.i
预处理做了什么
头文件包含:将#include指令指定的头文件内容插入到源代码中。这有助于实现代码的重用和模块化。
宏定义替换:将#define定义的宏在代码中进行替换。这有助于简化代码和提高代码的可读性。
条件编译:根据条件编译指令(如#ifdef、#ifndef、#endif)选择性地编译代码的一部分。这有助于在不同的编译环境下编译出不同的版本。
实验
# 0 "test.c"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "test.c"
int main()
{
return 0;
}
上面就是一个简单的c语言预处理后的样子
上面的那一段信息是给编译器看的包括名字、命令、隐形包含的头文件stdc-predef.h
stdc-predef.h
这个头文件之所以会被包含,主要是因为它是编译器(如 GCC)在预处理阶段自动插入的一个内部头文件,用于定义一些预处理器宏和类型定义,这些定义通常是与编译器和平台相关的。这个头文件并不是用户直接编写的,也不是用户需要显式包含的,而是由编译器在编译过程中根据需要自动处理的。具体来说,
stdc-predef.h
可能包含以下类型的定义:
预处理器宏:这些宏可能用于标识编译器的版本、目标平台、操作系统等。例如,可能包含定义编译器名称、版本号的宏,或者定义目标平台特性的宏(如是否支持特定类型的内存模型或指令集)。
类型定义:虽然
stdc-predef.h
通常不直接定义用户可见的类型(这些类型通常由标准库头文件如<stddef.h>
、<stdint.h>
等定义),但它可能包含一些与编译器内部实现相关的类型定义,这些类型在编译器的内部表示中使用。平台特定的宏:这些宏可能用于条件编译,以便在不同的平台上编译相同的代码时能够包含或排除特定的代码段。
需要注意的是,由于
stdc-predef.h
是编译器内部使用的头文件,因此其内容和行为可能会随着编译器的不同版本和配置而有所变化。用户通常不需要关心这个头文件的具体内容,因为它是由编译器自动处理的。在查看预处理后的
.i
文件时,可能会看到类似# 1 "/usr/include/stdc-predef.h"
的行,这表示编译器在预处理阶段自动插入了stdc-predef.h
头文件的内容。这是编译器内部机制的一部分,用于确保编译过程能够正确地处理与编译器和平台相关的定义。
创建个头文件
int def1 = 0;
int def2 = 1;
char s[10] = {"Hello!"};
# 0 "test.c"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "test.c"
# 1 "test.h" 1
int def1 = 0;
int def2 = 1;
char s[10] = {"Hello!"};
# 2 "test.c" 2
# 11 "test.c"
int main()
{
int a,c,b,d,e,f,g;
a = 1;
b = 1;
c = 1;
d = 1;
e = 1;
f = 1;
g = 1;
return 0;
}
也就是说出了我们主动包含的头文件,编译器还会自动包含一些头文件
比如这个程序我忘记包含stdio.h了但是仍然可以打印出来