49

C 风格的宏名称是否遵循与标识符相同的命名规则?编译器升级后,它现在针对旧版应用程序发出此警告:

warning #3649-D: white space is required between the macro name "CHAR_" and its replacement text
  #define         CHAR_&        38

这行代码为 & 符号定义了一个 ASCII 值常量。

#define   DOL_SN        36
#define   PERCENT       37
#define   CHAR_&        38
#define   RT_SING       39
#define   LF_PAR        40

我假设这个定义(据我所知,实际上并没有被任何代码引用)是错误的,应该更改为“CHAR_AMPERSAND”之类的东西?

4

4 回答 4

44

宏名称只能由字母数字字符和下划线组成,即'a-z''A-Z''0-9''_',并且第一个字符不能是数字。一些预处理器也允许使用美元符号字符'$',但你不应该使用它;不幸的是,我不能引用 C 标准,因为我没有它的副本。

GCC 文档

预处理标记分​​为五类:标识符、预处理数字、字符串文字、标点符号等。标识符与 C 中的 标识符相同:任何以字母或下划线开头的字母、数字或下划线序列。C的关键字对预处理器没有意义;它们是普通的标识符。例如,您可以定义名称为关键字的宏。唯一可以被视为预处理关键字的标识符是 defined. 请参见定义。

对于使用 C 预处理器的其他语言来说,这主要是正确的。但是,即使在预处理器中,C++ 的一些关键字也很重要。请参阅 C++ 命名运算符。

在 1999 C 标准中,标识符可能包含不属于“基本源字符集”的字母,由实现自行决定(例如带重音的拉丁字母、希腊字母或中国表意文字)。这可以通过扩展字符集或'\u'转义'\U'序列来完成。这个特性在 GCC 中的实现是实验性的;此类字符仅在 '\u'and'\U'形式中被接受,并且仅在 使用时才被接受-fextended-identifiers

作为扩展,GCC 将'$'其视为一个字母。这是为了与某些系统兼容,例如 VMS,其中'$' 通常用于系统定义的函数和对象名称。'$'不是严格符合模式的字母,或者如果您指定了-$选项。请参阅调用。

于 2008-12-15T20:02:23.957 回答
16

clang允许很多“疯狂”的角色..虽然我一直在努力寻找任何押韵或理由——至于为什么 有些被允许,而有些则不允许。例如..

#define   ?:          /// WORKS FINE
#define  ■  @end        /// WORKS FINE
#define   @interface  /// WORKS FINE
#define P  @protocol   /// WORKS FINE

然而

#define ☎   TEL     /// ERROR: Macro name must be an identifier.
#define ❌   NO     /// ERROR: Macro name must be an identifier.
#define ⇧   UP      /// ERROR: Macro name must be an identifier.
#define 〓   ==     /// ERROR: Macro name must be an identifier.
#define   APPLE   /// ERROR: Macro name must be an identifier.

谁知道。 我很想……但到目前为止,谷歌让我失望了。任何有关该主题的见解,将不胜感激™️。

于 2015-12-16T14:57:26.033 回答
8

没错,就名称而言,相同的规则适用于宏和标识符:有效字符是 [A-Za-z0-9_]。

使用大写名称将宏与其他标识符(变量和函数名称)区分开是很常见的用法。

于 2008-12-15T20:06:26.057 回答
1

为变量名称指定有效标识符的相同规则适用于宏名称,但宏可能具有与关键字相同的名称。标识符名称中的有效字符包括digits并且non-digits不能以数字开头。 non-digits包括大写字母 AZ、小写字母 az、下划线和任何实现定义的字符。

于 2008-12-15T20:07:59.203 回答