首页 > 解决方案 > 编译器忽略 #include 指令是否合法?

问题描述

据我了解,在编译编译单元时,编译器的预处理器通过将在和(或)标记之间指定#include的头文件1的内容扩展为当前编译单元来翻译指令。<>"

我的理解也是,大多数编译器都支持该#pragma once指令,以防止由于多次包含同一标头而导致多次定义的符号。遵循 include 保护习语可以产生相同的效果。

我的问题有两个:

  1. #include如果编译器以前遇到过#pragma once指令或在此标头中包含保护模式,则编译器完全忽略指令是否合法?
  2. 特别是对于 Microsoft 的编译器,标头是否包含#pragma once指令或包含保护模式在这方面有什么区别?文档表明它们的处理方式相同,尽管有些用户非常强烈地认为我错了,所以我很困惑并希望得到澄清。

1 我在掩饰这样一个事实,即标题不一定是文件

标签: c++visual-c++

解决方案


如果编译后的程序无法判断编译器是否忽略了头文件,则在as-if 规则下忽略或不忽略它是合法的。

如果忽略文件导致程序具有与通过正常处理所有文件生成的程序不同的可观察行为,或者忽略文件导致无效程序而正常处理它不会,则忽略该文件是不合法的。这样做是一个编译器错误。

编译器编写者似乎确信忽略一个曾经见过的具有适当包含保护的文件不会对生成的程序产生影响,否则编译器将不会进行此优化。但也有可能他们都错了,并且有一个迄今为止没有人发现的反例。也有可能不存在这样的反例是一个没有人费心去证明的定理,因为它看起来很直观。


推荐阅读