我们在哪里使用.i文件以及如何生成它们?

问题描述 投票:0回答:2

我正在浏览 GCC 手册页,我发现了以下行:

 file.i
           C source code that should not be preprocessed.

我知道运行

gcc -E foo.c
会在预处理后停止编译器; 但创建
.i
文件的实际应用是什么?

还有一种方法可以生成除

.i
之外的
gcc foo.c -E > foo.i
文件吗?

c gcc file-extension
2个回答
20
投票

.i
文件也称为“纯C文件”。在预处理阶段

  1. 将包含头文件。

  2. 宏将被替换。

  3. 评论已被删除。

  4. 用于条件编译。 如果您查看

    .i
    文件,您可以看到这些内容。

生成

.i
文件的命令是-

gcc -E foo.c -o foo.i

10
投票

一个

file.i
文件是:

不应预处理的 C 源代码。

来源

man gcc
然后按/键搜索,搜索“
\.i
”。
详细步骤
man gcc
,然后按/键进行搜索,然后输入
\.i
,然后按Enter键,然后反复按n键直至找到。

这意味着

.i
文件是预处理过的源代码,因此它已经被预处理过。因此,它已经包含:

  1. 包含所有头文件
  2. 宏被替换
  3. 评论已删除

...正如 @Sathish 在他的回答中所述。

您还会注意到 gcc 添加的大量特殊“注释”现在以

#

 字符开头,例如:

# 1 "main.c" # 1 "<built-in>" # 1 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 1 "<command-line>" 2 # 1 "main.c" # 44 "main.c" # 1 "/usr/include/stdio.h" 1 3 4 # 27 "/usr/include/stdio.h" 3 4 # 1 "/usr/include/features.h" 1 3 4 # 374 "/usr/include/features.h" 3 4 # 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4

我不知道它们是什么,也不知道它们是做什么的。有知道的请告诉我。

请注意,像这样的简单程序:

#include <stdio.h> int main() { printf("hello world\n"); return 0; }
用这个编译:

gcc -Wall -std=c99 -O0 -save-temps=obj main.c -o ./bin/main
将生成一个大约 682 行长的 

main.i

 文件,上面显示的 
main()
 函数就在最后。

如何生成所有中间文件,包括

.i
文件:

我的偏好是在项目的本地

.i 文件夹中一次性生成 所有

 中间文件(
.o
.s
.i
,而不是仅使用 
-E
 生成 
bin
 文件)通过使用 
gcc
 
-save-temps=obj
 选项,如下所示:

mkdir bin gcc -save-temps=obj foo.c -o ./bin/foo
现在“foo/bin”目录中有以下文件:

foo # compiled binary program (AKA: combined "object file", # "executable", "binary", "program", or "machine code") foo.i # intermediate, preprocessed C file foo.o # individual object file foo.s # assembly file

当然运行程序:

./bin/foo
关于“目标文件”和“可执行文件”的注释

请注意,最终输出,

foo

可执行文件,称为“
编译的二进制程序”,“程序”,(组合)“目标文件”,“可执行文件”,“二进制” ”,或者只是“机器代码”,或者“个和零”(10101010)。它是一个采用 对象文件格式 对象文件,单个 *.o
 
对象文件 也由 链接器 组合成一个来创建它。链接器将所有 *.o
 目标文件合并为一个,以便生成最终的 
foo
 可执行文件,或组合的 
目标文件

GNU 链接器 (

ld

) 手册的说明如下。请参阅“3.1 基本链接描述文件概念”部分:
https://sourceware.org/binutils/docs/ld/Basic-Script-Concepts.html#Basic-Script-Concepts(添加了强调,以及方括号中的内容[]
):

3.1 基本链接描述文件概念

我们需要定义一些基本概念和词汇来描述链接描述语言。

链接器将输入文件[各个

*.o

目标文件]组合成一个
单个输出文件。输出文件和每个输入文件都采用特殊的数据格式,称为目标文件格式。每个文件称为目标文件。输出文件通常称为“可执行文件”,但出于我们的目的,我们也将其称为目标文件。除其他外,每个目标文件都有一个sections列表。我们有时将输入文件中的某个部分称为“输入部分”;类似地,输出文件中的部分是输出部分 了解更多信息。关于目标文件,您还可以在这里看到我的其他两个答案:

如何在编译时知道STM32的闪存和动态存储器(SRAM)已使用了多少?

  1. 将 binutils `size` 输出从“sysv”格式(`size --format=sysv my_executable`)转换为“berkeley”格式(`size --format=berkeley my_executable`)
  2. 另请参阅
  3. @Ciro Santilli OurBigBook.com 的回答:
如何查看 C 预处理器输出?

© www.soinside.com 2019 - 2024. All rights reserved.