#pragma 一次与包括警卫
#pragma once vs. include guards
我正在通过实现定义的行为控制
关于#pragma once
有以下文字:
与标头保护不同,此编译指示使得不可能在多个文件中错误地使用相同的宏名称。
我不确定这意味着什么。有人可以解释一下吗?
蒂亚
示例:
// src/featureA/thingy.h
#ifndef HEADER_GUARD_FOR_THINGY
#define HEADER_GUARD_FOR_THINGY
struct foo{};
#endif
// src/featureB/thingy.h
#ifndef HEADER_GUARD_FOR_THINGY
#define HEADER_GUARD_FOR_THINGY
struct bar{};
#endif
// src/file.cpp
#include "featureA/thingy.h"
#include "featureB/thingy.h" // oops, this file is removed by header guard
foo f;
bar b;
标头保护宏需要一丝不苟的努力才能保持其唯一性。#pragma once
会自动执行此操作。
为了公平和完整起见,让我提到缺点(也在链接页面中):如果从多个路径包含同一个文件,#pragma once
则无法识别该文件。对于具有奇异文件结构的项目来说,这可能是一个问题。例:
// /usr/include/lib.h
#pragma once
struct foo{};
// src/ext/lib.h
#pragma once
struct foo{};
// src/headerA.h
#pragma once
#include <lib.h>
// src/headerB.h
#pragma once
#include "ext/lib.h"
// src/file.cpp
#include "headerA.h"
#include "headerB.h" // oops, lib.h is include twice
foo f;
假设你有一个头文件 File1.h。您使用以下命令创建了 File1.h:
#ifndef FILE_1_H
#define FILE_1_H
// Contents of File1.h
#endif
该语言中没有任何内容可以阻止其他头文件使用相同的宏,FILE_1_H
,就像包含保护一样。
- 您使用的库中的头文件可能已经定义了这一点。
- 由于复制和粘贴错误,您可以在自己的代码库中的 File2.h 中使用相同的标头保护。
发生这种情况时,.cpp文件中只能#include
一个 .h 文件。在最好的情况下,您将收到编译器错误,这些错误将允许解决问题。在最坏的情况下,您最终将使用错误的类型或函数,并且问题将在运行时表现出来。
由于这些原因,包含防护装置不坚固,容易出现用户错误。
但是,如果您的编译器支持它并且您使用
#pragma once
在所有头文件中,将避免此类错误。
请注意,使用
#pragma once
有其自身的缺点。有关此内容的更多信息,请参阅以下内容:
#pragma 曾经是保险箱吗?
使用一次 #pragma 有什么危险?
包括守卫看起来像这样:
#ifndef SOME_NAME
#define SOME_NAME
// The header file contents
#endif
虽然有命名约定,但没有什么可以强制宏(在本例中为SOME_NAME
)实际调用什么。如果尝试包含两个使用相同宏名称的头文件,编译器将看不到第二个文件的内容,因为该文件的#ifndef ___
将失败(宏已在第一个文件中定义)。
#pragma once
不存在此问题。
相关文章:
- 我是否需要在下一次转移时将所有权*转移回转移队列
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 在C++中一次将矢量值写入多个文件
- 循环中的条件:为什么每次都调用strlen(),而vector.size()只调用一次
- 为什么 zlib 放气初始化调用一次不起作用?
- 在一次迭代中从 txt 文件中读取多行
- 为什么无论你输入什么,这"while(cin.get(str,3))"只运行一次?
- 在头文件和 cpp 文件中使用一次 #pragma 时出现结构重定义错误
- 有没有办法一次声明相同类型的多个对象,并通过一个表达式立即使用相同的右值初始化它们?
- 高级选择排序 - 在一次迭代中搜索两个元素
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 如何仅使用一次固定<<设置精度(2)?或者至少恢复到默认行为?
- 什么是仅调用一次并调用参数的控制台应用
- 如何确保用户在一行上提示输入一次时输入名字和姓氏?
- (C++)虽然循环一次不起作用,但我引入了多个变量
- 为什么我的信号处理程序只执行一次?
- 如何使用C++一次读取整个二进制文件
- 花括号使循环运行一次?
- #pragma 一次与包括警卫
- 何时使用包括防护装置或 #pragma 一次C++