令人沮丧的实用主义者使用GCC

Discouraged pragma use GCC

本文关键字:主义者 GCC      更新时间:2023-10-16

几乎所有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。不要为使用它而感到难过。