首页 > 解决方案 > 为什么同时使用 #pragma 并包含警卫?

问题描述

我正在研究 boost 库,对我来说奇怪的是许多库都使用这种代码:

#ifndef BOOST_SERIALIZATION_ACCESS_HPP
#define BOOST_SERIALIZATION_ACCESS_HPP

// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif

MSDN 明确指出:

在同一个文件中同时使用 #include 保护习语和 #pragma 没有任何优势

我不明白可能是什么原因。无论如何,包括守卫都可以完成这项工作,那么为什么我们还要费心编写一次编译指示呢?

标签: c++boostc-preprocessor

解决方案


实际上编译器内部可能存在细微差别。当编译器遇到#pragma once然后它可以在内部标记这个文件被包含。当它#include第二次遇到这个文件时,它甚至不会费心打开它,它会忽略该#include语句。

只有包含保护,预处理器必须在每次包含时解析整个文件以找到匹配的#endif. 从理论上讲,如果多次包含非常复杂且大型的包含文件,这可能会影响编译时间。

除此之外,包括警卫和#pragma once行为方式相同。通常使用这两种方法,因为#pragma once不能保证所有编译器都支持。

编辑:

编译器可能有能力检测包含保护的语句围绕整个文件的代码并推断它是一个包含保护,从而产生与 with 完全相同的行为#pragma once。如果是这样,那么 MSDN 的说法是正确的。


推荐阅读