c++ - 编译器忽略 #include 指令是否合法?
问题描述
据我了解,在编译编译单元时,编译器的预处理器通过将在和(或)标记之间指定#include
的头文件1的内容扩展为当前编译单元来翻译指令。<
>
"
我的理解也是,大多数编译器都支持该#pragma once
指令,以防止由于多次包含同一标头而导致多次定义的符号。遵循 include 保护习语可以产生相同的效果。
我的问题有两个:
#include
如果编译器以前遇到过#pragma once
指令或在此标头中包含保护模式,则编译器完全忽略指令是否合法?- 特别是对于 Microsoft 的编译器,标头是否包含
#pragma once
指令或包含保护模式在这方面有什么区别?文档表明它们的处理方式相同,尽管有些用户非常强烈地认为我错了,所以我很困惑并希望得到澄清。
1 我在掩饰这样一个事实,即标题不一定是文件。
解决方案
如果编译后的程序无法判断编译器是否忽略了头文件,则在as-if 规则下忽略或不忽略它是合法的。
如果忽略文件导致程序具有与通过正常处理所有文件生成的程序不同的可观察行为,或者忽略文件导致无效程序而正常处理它不会,则忽略该文件是不合法的。这样做是一个编译器错误。
编译器编写者似乎确信忽略一个曾经见过的具有适当包含保护的文件不会对生成的程序产生影响,否则编译器将不会进行此优化。但也有可能他们都错了,并且有一个迄今为止没有人发现的反例。也有可能不存在这样的反例是一个没有人费心去证明的定理,因为它看起来很直观。
推荐阅读
- windows - 如何从 Appdata\Local\assembly\tmp 限制/清理我的 DLL
- html - 调整 svg 文件中一组路径的大小
- c# - 如何重命名 COM DLL
- spring - Spring Kafka Producer 日志记录
- ios - 在每 x 次加载的 viewdidload 上显示插页式广告
- jquery - Loop through span and find the closest check box
- git - 设置 git-svn 存储库,其中 svn trunk/tags/branches 组织在模块子文件夹中
- c# - 我不能将脚本分配给 UNITY 中的按钮?
- html - 应用了渐变的图像:通过 css 添加渐变或将它们直接应用于 src img 的性能更好?
- python - 无限期运行python脚本