在C / C ++预处理器中,在其自己的行上加一个井号/井号(#)的目的是什么?


145

我一直在看Boost库的源代码,并且我注意到通常有单个磅号,但没有附加任何预处理程序指令。我通读了GCC预处理程序手册和规范指南,但找不到任何相关内容。

(1) #ifndef BOOST_CONFIG_HPP
(2) #  include <boost/config.hpp>
(3) #endif
(4) #
(5) #if defined(BOOST_HAS_PRAGMA_ONCE)
(6) #  pragma once
(7) #endif

在第4行,英镑符号后面没有任何内容。这有什么作用?它在C预处理程序(CPP)规范中定义吗?

由于Boost是跨平台的库,因此我认为任何CPP都应正确解析它。在整个代码中具有随机的磅/哈希符号会产生什么影响/副作用?


6
@Zaibis例如 GCC套件中预处理器的可执行文件名为“ cpp”(而编译器为gcc和g ++)
deviantfan

3
CPP代表C-Plus-Plus。
djeidot


7
@djeidot“ cpp”是不明确的。这就是为什么人们在引用C-Plus-Plus时使用“ c ++”或“ cxx”(x看起来像+ +旋转了45度)。
Mike Ounsworth

12
@djeidot不,CPP是C预处理程序。它的存在早于C ++的存在。
Leandros

Answers:


185

一个#对自己上线已经完全没有效果。我认为它被用于美学价值。

C标准说:

6.10.7空指令

语义学

形式的预处理指令

# new-line

没有效果。

C ++标准说了同样的话:

16.7空指令[cpp.null]

形式的预处理指令

# new-line

没有效果。


4
但是,这并没有解释使用它的目的,也没有给出其存在的理由。
StellarVortex

8
“这有什么作用?它在C预处理程序(CPP)规范中定义了吗?……在整个代码中具有随机的井字/哈希符号会产生什么作用/副作用?” 那就是我的回答。它没有效果,但是我不想推测作者使用它的原因。我现在已经这样做了。
乔纳森·韦基利

您得到了正确的答案,这对预处理器毫无意义。我将推测这可能有助于其他某些程序(例如IDE或LINT)将一组指令作为逻辑单元保持在一起。一些IDE允许程序员扩展或折叠文本块,以帮助他们跟踪文件的逻辑结构。
斯宾塞

107

它使源代码看起来很漂亮,仅此而已。

强调了整个块是预处理器部分的事实。

确实,C和C ++预处理器都必须#在一行上忽略。


16
也使得在一些文本编辑器(如导航更容易{}在VIM)。
wchargin '16

@WChargin,这取决于您如何看待它。如果要导航到两个预处理器块之间,则添加#将阻止您使用{}。实际上,按}两次以跳过该块(在OP的示例中)可能比不能够跳转到两个块的中间要容易得多。
Shahbaz

3
@Shahbaz当然!我的经验法则是“将逻辑单元保持在一起”,因此“段落”实际上意味着“想法”。我也将在预处理器声明中遵循此规则。当然,这很大程度上取决于个人风格。
wchargin '16

46

始终检查权威来源,而不要依赖其他资源。C标准化为ISO 9899 :: 2011,C ++也具有ISO标准。两者都广为接受,并且可以通过简短搜索获得最终草案。C标准在6.10.7声明(C ++的文字大致相同):

形式的预处理指令

# new-line

没有效果。

这是一个空指令,就像;在核心语言中没有前面的表达式的是空语句一样

对于预处理器而言,仅出于格式/可读性的考虑,突出显示了各行在语义上属于同一行。(分号OTOH在语义上相关)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.