有如果SOME_HEADER_H
已经定义被包括在报头的前面,然后,在第二情况下,预处理器将处理#pragma once
在一个微妙的差异,并且在第一它不会。
你会用同样的TU再次看到一个功能上的差异,如果你#undef SOME_HEADER_H
,包括文件:现在
#define SOME_HEADER_H
#include "some_header.h"
#undef SOME_HEADER_H
#include "some_header.h"
,如果1我有头文件中的所有定义。在情况2中,我没有。
即使没有#undef
,由于在情况1中忽略了#pragma once
,您可以想象会看到预处理时间的差异。这取决于实施。
我能想到的它可能已经是第一个包含这个头文件之前定义两种可能的方式:
- (明显的一个),一个完全独立的文件定义它,无论是故意或意外名称冲突,
- 该文件的副本已经定义了它。取决于可能包括这种文件在两个不同文件名下涉及相同TU的情况的实施方式,例如,由于符号链接或文件系统合并。如果你的实现支持
#pragma once
,并且你仔细检查它的文档,你可能能够找到一个明确的声明,说明优化是通过包含文件的路径来应用的,还是通过比较标识文件存储的东西inode号码。如果是后者,你甚至可以找出是否仍然存在诈骗行为,可能被拉扯欺骗预处理,如远程安装一个本地文件系统,以掩盖它的“同一个文件真正” ...
用于以预期的方式,但是,没有提供的实施,微软定义的方式对待#pragma once
差异。只要它被处理而不是被跳过,它就会标记包含文件以进行优化,所以无论它是否会在文件中进行第二遍处理都无关紧要 - 第二遍不会发生。
,因为编译是非标准的,至少在理论上它可以有不同的实现方式完全不同的含义,在这种情况下,当多少次对其进行处理,可能无关紧要,当然还有。在实践中,你会认为没有人会这样做。
将两者都包含在内是相当多余的,你不觉得吗?我只是使用这些定义来检查。的 – 2011-03-21 19:15:27
可能重复[曾经的#pragma VS包括警卫?](http://stackoverflow.com/questions/1143936/pragma-once-vs-include-guards) – Jon 2011-03-21 19:27:39
@Tim:他们是在编译器非冗余那识别一次“编译指示”,但不执行gcc所做的巧妙优化,以便在标题保护允许它不会再次访问文件时识别。至少某些版本的MSVC处于该状态,不知道最新的。 – 2011-03-21 19:32:46