【问题标题】:gcc flag -include ignored when compiling .i or .ii files编译 .i 或 .ii 文件时忽略 gcc 标志 -include
【发布时间】:2019-10-29 04:58:16
【问题描述】:

我最近发现如果文件结尾是 .i 或 .ii,gcc 会跳过预处理,并决定试一试。编译一个不包含 stdio.h 的 hello world 程序:

gcc -Wall file.c; # compiles with preprocessor, implicit declaration of puts
gcc -Wall file.i; # compiles without preprocessor, implicit declaration of puts 

如果没有预处理器指令,我不能包含 stdio.h,但我记得 gcc 的 -include 标志可用于“强制包含”标头。它导致了以下测试:

gcc -Wall -include stdio.h file.c; # no warnings, "hello world". hooray
gcc -Wall -include stdio.h file.i; # implicit declaration of puts WAIT WHAT?!

如果在没有预处理的情况下编译文件,我觉得 gcc 不包含 stdio.h 很奇怪。更奇怪的是如何没有发出警告; -include stdio.h 没有明显效果,充其量是gcc的错误使用。

为什么它不起作用?

GCC 版本 6.3.0。

【问题讨论】:

  • -E选项生成预处理文件,test.c生成test.i。因此,查看 .i 文件扩展名并将其用作不再运行预处理器的提示似乎是硬编码的。只需选择另一个扩展程序。

标签: c gcc preprocessor


【解决方案1】:

-include 列在Preprocessor Options 下:

3.12 控制预处理器的选项

这些选项控制 C 预处理器,它在实际编译之前在每个 C 源文件上运行。

[...]

-include <em>file</em>

处理文件,就像#include "file" 出现在主源文件的第一行一样。 [...]

但是,对于.i 文件,预处理器从不运行,因此该选项无效。

GCC 通常不会对无效的选项发出警告。您也可以运行gcc -Wall -funsigned-char foo.o,它甚至不会调用编译器。 -Wall-funsigned-char 会被忽略。

您可以将编译视为一个管道:

  1. C 代码 (.c) 通过预处理器,生成 ...
  2. 预处理的 C 代码 (.i),由编译器处理,生成 ...
  3. 汇编代码(.s),由汇编程序处理,产生...
  4. 目标代码(.o),由链接器处理,给你...
  5. 一个可执行文件。

文件名告诉 GCC 从哪个阶段开始。

选项可以用来告诉 GCC 在哪里停止:

  • -P 预处理后停止
  • -S 编译后停止
  • -c 组装后停止

其他选项被传递到管道中的相应阶段。如果管道的那部分从未运行,则什么都不会发生。

【讨论】:

  • "这些选项控制 C 预处理器" - 这部分是清楚的。我错误地认为-include 控制的是编译器,而不是预处理器。
【解决方案2】:

这是有道理的。 .i 文件已经过预处理,因此没有预处理步骤,因此没有包含。

对已经预处理的文件进行操作是一个非常高级的话题,所以他们可能只是假设任何人都知道他们在做什么。

或者也许这只是一个疏忽,你应该得到一个警告。

【讨论】:

    【解决方案3】:

    来自GCC documentation

    -包括文件

    处理文件,就像#include "file" 出现在主源文件的第一行一样。但是,搜索 file 的第一个目录是预处理器的工作目录而不是包含主源文件的目录。如果在此处未找到,则会照常在 #include "…" 搜索链的其余部分中进行搜索。

    如果给出多个-include options,则文件将按照它们在命令行中出现的顺序包含在内。

    第一句话

    处理文件,就像#include "file" 出现在主源文件的第一行一样。

    表示人们会期望您看到的行为。

    如果 GCC 不应用预处理指令,它不会包含该文件,因为它不会盲目地将 stdio.h 的内容添加到正在编译的文件的前面,它就像添加了预处理器一样包含指令。

    【讨论】:

      猜你喜欢
      • 2019-05-22
      • 1970-01-01
      • 1970-01-01
      • 2013-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-16
      • 2021-02-21
      相关资源
      最近更新 更多