c++ - 使用#pragma once 有什么危险?

标签 c++ c macros

<分区>

现代 C 和 C++ 编译器支持非标准的 #pragma once 预处理器指令,其目的与经典的头文件保护类似:

#ifndef hopefully_unique_identifier_that_doesnt_hurt_the_code
#define hopefully_unique_identifier_that_doesnt_hurt_the_code
  // some code here
#endif

一个问题,我知道,经典的方法是,一旦你包含了一个标题,你必须 #undef 标题保护宏来再次包含它(这样做,对我来说,这是一个主要的代码味道,但这不是重点)。 #pragma once 方法也会出现同样的问题,但不可能允许多次包含 header 。

经典方法的另一个问题是,您可能会不小心在不相关的地方定义相同的宏,因此要么没有按预期包含 header ,要么做了一些我无法想象的其他令人讨厌的事情。这在实践中很容易避免,通过遵守某些约定,例如将宏基于类似 UUID 的对象(即随机字符串)或(不太理想的方法),将它们基于文件名,它们在中定义.

我在现实生活中很少遇到这些潜在问题,所以我真的不认为它们是主要问题。

我能想到的关于 #pragma once 的唯一潜在现实问题是,它不是一个标准的东西——你依赖的东西可能不是随处可用的,即使它在实践中无处不在 (*)。

那么,除了我已经提到的问题之外,#pragma once 还存在哪些潜在问题?我是不是太相信它在实践中随处可用?

(*) 排除一些只有少数人使用的小型编译器。

最佳答案

我在使用 #pragma once 时遇到的一个问题是包含位于多个位置的同一文件。使用 #pragma once 它被认为是不同的,而不是使用 #ifndef/#define 守卫。

关于c++ - 使用#pragma once 有什么危险?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47830610/

相关文章:

c# - 是否可以执行存储在变量中的机器代码?

c++ - 在派生的 QObject 构造函数中连接 Qt 信号和槽

macros - 如何将命名循环标签传递给 Rust 中的宏?

c++ - <命令行> :0:3: warning: ISO C++11 requires whitespace after the macro name

c++ - 使用 C++ 宏从嵌套括号中提取项目

c++ - 什么是 undefined reference /未解析的外部符号错误以及如何修复它?

c++ - 指向 cv 和/或 ref 限定成员函数的指针的 Typedef

更改指针类型导致写访问异常

c - 为变量指定一个数字

c - 使用 #define #ifdef 作为条件