将#pragma放在包围守卫中而不是外部是否有区别?
情况1:
#ifndef SOME_HEADER_H #define SOME_HEADER_H #pragma once
情况2:
#pragma once #ifndef SOME_HEADER_H #define SOME_HEADER_H
我只是想知道好奇,如果有任何特殊情况,我应该喜欢一个或另一个(情况1或情况2),因为我已经决定在我的代码中组合(编译和标题).
编辑:
我想你们是在误解我的问题…我问一下pragma的位置,而不是pragma一次-vs-头卫.
解决方法
有一个微妙的区别,如果在包含头部之前已经定义了SOME_HEADER_H,那么在第二种情况下,预处理器将处理#pragma一次,在第一种情况下不会.
如果#undef SOME_HEADER_H并且通过相同的TU再次包含文件,您将看到功能上的差异:
#define SOME_HEADER_H #include "some_header.h" #undef SOME_HEADER_H #include "some_header.h"
现在,如果1我有头文件的所有定义.在情况2我没有.
即使没有#undef,您也可以看到预处理时间有所不同,因为#pragma在情况1中被忽略.这取决于实现.
我可以想到在首个包含这个头文件之前可以定义的两个可行的方法:
(明显的一个)一个完全独立的文件定义它,故意地或意外的名字冲突,
>这个文件的副本已经定义了.取决于可能包括此文件在两个不同文件名下涉及同一TU的情况的实现.因为符号链接或文件系统合并.如果您的实现支持#pragma一次,并仔细检查其文档,您可能可以找到一个明确的语句,无论优化是通过包含文件的路径应用的,还是通过比较标识文件存储的内容,像inode号.如果是后者,你甚至可以弄清楚是否还有一些骗局可能会被骗到预处理器,比如远程安装本地文件系统来隐藏它是“真正的文件”…
以预期的方式使用,但是没有区别,只要该实现按照Microsoft定义的方式处理#pragma一次.只要它被处理而不是跳过,它将标记包含的文件进行优化,因此无论是否在第二次传递文件时都会被处理 – 第二遍不会发生.
当然,由于编译指标是非标准的,至少在理论上它可能对不同的实现有一个完全不同的含义,在这种情况下,它可能与何时和多少次被处理有关.实际上,你会认为没有人会这样做.