星号不是字符常量?

The asterisk is not a character constant?

foo.cpp:

#define ID A
#if ID == A
#warning "hello, world"
#endif

使用 g++ -c foo.cpp 编译工作正常:(g++ v8.2.0)

foo.cpp:3:2: warning: #warning "hello, world" [-Wcpp]
 #warning "hello, world"
  ^~~~~~~

现在,如果我将 #define ID A 替换为 #define *,那么我会得到:

foo.cpp:1:12: error: operator '*' has no left operand
 #define ID *
            ^
foo.cpp:2:5: note: in expansion of macro ‘ID’
 #if ID == A
     ^~

*有什么特别之处?为什么它在 #if 表达式中失败?

#if does 不是你想的那样。

在您的第一个示例中,它尝试计算 0 == 0,这是一个值为 true.

的有效表达式

在您的第二个示例中,它尝试计算 * == 0,这不是一个有效的表达式。

您的 post 中有两点值得注意。首先,它并不像你想象的那样有效。这将 produce the warning too

#define ID B
#if ID == A
#warning "hello, world"
#endif

原因是在#if的上下文中,预处理标记IDA被当作宏来展开。由于未定义 A,因此 "expanded" 变为 0。ID 通过扩展 ID -> B -> 0 也是如此。所以这里的条件也是成立的。

这也回答了为什么 * 会导致错误。它无法进一步扩展(因为它不是有效标识符),因此您得到比较 * == 0,这是无意义的。

因为你的标题暗示你试图与一个字符常量进行比较,所以这样做的方法是定义 ID 以扩展 到一个字符的标记序列 字符常量。

#define ID 'A'
#if ID == 'A'

它现在应该可以正常工作了。也会 #define ID '*'