星号不是字符常量?
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
的上下文中,预处理标记ID
和A
被当作宏来展开。由于未定义 A
,因此 "expanded" 变为 0。ID
通过扩展 ID
-> B
-> 0
也是如此。所以这里的条件也是成立的。
这也回答了为什么 *
会导致错误。它无法进一步扩展(因为它不是有效标识符),因此您得到比较 * == 0
,这是无意义的。
因为你的标题暗示你试图与一个字符常量进行比较,所以这样做的方法是定义 ID
以扩展 到一个字符的标记序列 字符常量。
#define ID 'A'
#if ID == 'A'
它现在应该可以正常工作了。也会 #define ID '*'
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
的上下文中,预处理标记ID
和A
被当作宏来展开。由于未定义 A
,因此 "expanded" 变为 0。ID
通过扩展 ID
-> B
-> 0
也是如此。所以这里的条件也是成立的。
这也回答了为什么 *
会导致错误。它无法进一步扩展(因为它不是有效标识符),因此您得到比较 * == 0
,这是无意义的。
因为你的标题暗示你试图与一个字符常量进行比较,所以这样做的方法是定义 ID
以扩展 到一个字符的标记序列 字符常量。
#define ID 'A'
#if ID == 'A'
它现在应该可以正常工作了。也会 #define ID '*'