令人沮丧的实用主义者使用GCC
Discouraged pragma use GCC
几乎所有C++程序都需要头保护,但在严格执行命名约定时会很痛苦,尤其是在重构过程中。当使用GCC(和许多其他编译器)时,我们在预处理器命令#pragma once
中有一个替代方案。我看到的反对使用此命令的建议(例如,在v3.4之前缺乏支持)对我的个人项目来说不是很有说服力。如果可能的话,我想使用#pragma once
。
话虽如此,GCC网站上的这句话让我停顿了一下:
请注意,一般情况下,我们不建议使用杂注;请参阅函数属性,以了解进一步的解释。
也许这只是我较低的C++经验对我不利,但我在该链接指向的网站上看不到对该建议的任何解释。有人能用(半)外行的话解释他们推荐的理由吗?
一般建议来自这样一个事实,即不仅不能保证其他编译器实现#pragma once
(或任何其他pragma),也不能保证其他编译程序以GCC相同的方式实现#pragma once
。另一个编译器可以合法地赋予它一个完全不同的含义,或者更糟的是,一个微妙的不同含义。如果你不关心你的代码是可移植的,你可以忽略这个建议。
就我个人而言,我只是在自己的标题中使用普通的#ifndef
/#define
包含保护,即使是在我自己的个人项目中也是如此。它实际上并没有那么多打字,而且保证在任何地方都能工作。与保护宏的命名冲突对我来说从来都不是一个问题,我尽量不担心我没有的问题。
我曾经对各种C++编译器的文档进行过调查,这是调查的结果:
#if defined (_MSC_VER)
|| (defined (__BORLANDC__) && __BORLANDC__ >= 0x0650)
|| (defined (__COMO__) && __COMO_VERSION__ >= 400) /* ??? */
|| (defined (__DMC__) && __DMC__ >= 0x700) /* ??? */
|| (defined (__clang__) && __clang_major__ >= 3)
|| (defined (__GNUC__) && (__GNUC__ >= 4
|| (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)))
# define LOG4CPLUS_HAVE_PRAGMA_ONCE
# pragma once
#endif
正如您所看到的,#pragma once
受到所有主流编译器的支持。#pragma once
的维基百科页面证实了这一点。
因此,为了回答最初的问题,pragma的问题在于它们是非常特定于编译器的。这就是由于可移植性的原因,通常不鼓励使用它们的方式。OTOH,几乎所有C++编译器都支持这种特殊的pragma。不要为使用它而感到难过。
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 奇怪的结构&GCC&clang(void*返回类型)
- GCC本机矩阵运算库
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- gcc和c++17的过载解析失败
- 数据成员SFINAE的C++17测试:gcc vs clang
- GCC对可能有效的代码抛出init list生存期警告
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 使用gcc从静态链接的文件中查找可选符号
- 普通环路未使用gcc 4.8.5自动矢量化
- 有了gcc,是否可以链接库,但前提是它存在
- 在clang++预处理器中确定gcc工具链版本
- 为什么 gcc 编译这个而 msvc 没有
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- 如何使用Clang/GCC在Mac上为C/C++设置VSCode
- 令人沮丧的实用主义者使用GCC