提问人:Vinod 提问时间:2/23/2019 更新时间:2/23/2019 访问量:6872
#pragma 一次与包括守卫 [重复]
#pragma once vs. include guards [duplicate]
问:
我正在通过实现定义的行为控制
并且有以下与以下相关的文字:#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;
评论
#pragma once
假设您有一个头文件 File1.h。您使用以下命令创建了 File1.h:
#ifndef FILE_1_H
#define FILE_1_H
// Contents of File1.h
#endif
该语言中没有任何内容可以阻止其他头文件使用相同的宏,如包含防护。FILE_1_H
- 您使用的库中的头文件可能已经定义了这一点。
- 由于复制和粘贴错误,您可以在自己的代码库中使用 File2.h 中的相同标头保护。
发生这种情况时,.cpp文件中只能有一个 .h 文件。在最好的情况下,您将收到编译器错误,从而可以解决问题。在最坏的情况下,您最终会使用错误的类型或函数,并且问题将在运行时表现出来。#include
由于这些原因,包含防护不可靠,并且容易受到用户错误的影响。
但是,如果您的编译器支持它,并且您使用
#pragma once
在所有头文件中,将避免此类错误。
请注意,使用
#pragma once
有其自身的一系列缺点。有关详细信息,请参阅以下内容:
#pragma 曾经是保险箱吗?
使用一次 #pragma 有什么危险?
评论
#pragma once
包括防护如下所示:
#ifndef SOME_NAME
#define SOME_NAME
// The header file contents
#endif
虽然有命名约定,但没有什么可以强制执行宏(在本例中)的实际调用。如果尝试包含两个使用相同宏名称的头文件,则编译器将看不到第二个文件的内容,因为该文件将失败(宏已在第一个文件中定义)。SOME_NAME
#ifndef ___
此问题不存在。#pragma once
评论
#pragma once
#pragma 一次
文件会根据其文件系统级标识被排除,因此如果标头存在于项目中的多个位置,则无法防止包含两次标头。#pragma once
#pragma once
评论
#pragma once
#pragma once