Mar*_*lon 10 c c++ include-guards
放置#pragma once包含防护装置内部而不是外部防护装置之间有什么区别吗?
情况1:
#ifndef SOME_HEADER_H
#define SOME_HEADER_H
#pragma once
Run Code Online (Sandbox Code Playgroud)
案例2:
#pragma once
#ifndef SOME_HEADER_H
#define SOME_HEADER_H
Run Code Online (Sandbox Code Playgroud)
我只是出于好奇而想知道是否有任何特殊情况我应该更喜欢其中一个(案例1或案例2),因为我决定在我的代码中将两者(pragma和header guard)结合起来.
编辑:
我想你们都误解了我的问题......我问的是一个地方pragma once,而不是pragma曾经-vs-标题守卫.
有一个细微的区别,如果SOME_HEADER_H在包含标题之前已经定义了,那么在第二种情况下预处理器将处理#pragma once,而在第一种情况下它不会.
如果您#undef SOME_HEADER_H通过相同的TU再次包含该文件,您将看到功能差异:
#define SOME_HEADER_H
#include "some_header.h"
#undef SOME_HEADER_H
#include "some_header.h"
Run Code Online (Sandbox Code Playgroud)
现在,在第1种情况下,我拥有头文件中的所有定义.在案例2中,我没有.
即使没有#undef,你可以想象由于#pragma once在案例1中被忽略而导致预处理时间的差异.这取决于实现.
在第一次包含此头文件之前,我可以想到它已经可以定义的两种合理方式:
#pragma once,并仔细检查其文档,您可能能够找到一个明确的声明,无论是通过包含文件的路径应用优化,还是通过比较标识文件存储的内容,如inode数.如果是后者,您甚至可以弄清楚是否仍然存在可以被欺骗以欺骗预处理器的诈骗,例如远程安装本地文件系统以隐藏它"真的是同一个文件"......但是,按照预期的方式使用,只要实现#pragma once以微软定义它的方式处理,就没有区别.只要它被处理而不是跳过,它就会标记优化的包含文件,因此无论是否在第二次通过文件时处理它都无关紧要 - 第二次传递不会发生.
当然,因为编译指示是非标准的,至少在理论上它可能在不同的实现上具有完全不同的含义,在这种情况下,处理它的时间和次数可能很重要.在实践中,你认为没有人会这样做.
他们是多余的.
#pragma once并不是所有编译器都支持,而包括警卫.只需使用包含警卫.像gcc这样的编译器非常聪明,可以理解包含警卫,甚至不再打开文件.