C++ 星号不是字符常量?
C++ 星号不是字符常量?,c++,gcc,g++,c-preprocessor,preprocessor,C++,Gcc,G++,C Preprocessor,Preprocessor,foo.cpp: #define ID A #if ID == A #warning "hello, world" #endif 使用g++-cfoo.cpp编译工作正常:(g++v8.2.0) 现在,如果我将#define ID A替换为#define*,那么我得到: foo.cpp:1:12: error: operator '*' has no left operand #define ID * ^ foo.cpp:2:5: note: in expansion
foo.cpp
:
#define ID A
#if ID == A
#warning "hello, world"
#endif
使用g++-cfoo.cpp编译工作正常:(g++v8.2.0)
现在,如果我将#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
不是您认为它正在做的事情
在第一个示例中,它尝试计算0==0
,这是一个值为true
的有效表达式
在第二个示例中,它尝试计算*==0
,这不是一个有效的表达式。#如果不是您认为它在做的事情
在第一个示例中,它尝试计算0==0
,这是一个值为true
的有效表达式
在您的第二个示例中,它尝试计算*==0
,这不是一个有效的表达式。在您的帖子中有两件事需要注意。第一,它不像你想象的那样有效。这将
原因是在#if
的上下文中,预处理标记ID
和A
被视为宏并被展开。由于未定义A
,因此将其“扩展”为0。通过扩展ID
->B
->0
,ID也一样。所以这里的条件也是正确的
这也回答了*
导致错误的原因。它不能进一步扩展(因为不是有效的标识符),因此您会得到比较*==0
,这是毫无意义的
由于您的标题意味着您试图与字符常量进行比较,因此,这样做的方法是定义ID
以扩展到字符常量的标记序列
#define ID 'A'
#if ID == 'A'
它现在应该如预期的那样工作。正如定义ID“*”
一样,在你的帖子中有两件事值得注意。第一,它不像你想象的那样有效。这将
原因是在#if
的上下文中,预处理标记ID
和A
被视为宏并被展开。由于未定义A
,因此将其“扩展”为0。通过扩展ID
->B
->0
,ID也一样。所以这里的条件也是正确的
这也回答了*
导致错误的原因。它不能进一步扩展(因为不是有效的标识符),因此您会得到比较*==0
,这是毫无意义的
由于您的标题意味着您试图与字符常量进行比较,因此,这样做的方法是定义ID
以扩展到字符常量的标记序列
#define ID 'A'
#if ID == 'A'
它现在应该如预期的那样工作。正如#定义ID'*'
一样,*
是一个操作符,不能成为标识符的一部分,因为只有[A-Za-z0-9.
被允许*
是一个操作符,并且不能成为标识符的一部分,因为只有[A-Za-z0-9.
被允许,谢谢!不知何故,我假设在C++预处理器中,普通的单字母标识符充当字符常量。也许您可以添加为什么*
无法进一步扩展?(我猜想,因为它不是一个有效的标识符。)不幸的是,从a
切换到'a'
会产生其他问题,因为我想使用#a
作为组装特定于ID的包含文件名的一部分。@feklee-在我的答案中添加了这一小贴士。因为您使用的是GCC,所以可以尝试查看它的扩展。IIRC#$
或#@
生成字符,与标准#
生成字符串文字相同。@
是。它被称为charizing操作符,似乎没有GCC的等价物。谢谢!不知何故,我假设在C++预处理器中,普通的单字母标识符充当字符常量。也许您可以添加为什么*
无法进一步扩展?(我猜想,因为它不是一个有效的标识符。)不幸的是,从a
切换到'a'
会产生其他问题,因为我想使用#a
作为组装特定于ID的包含文件名的一部分。@feklee-在我的答案中添加了这一小贴士。因为您使用的是GCC,所以可以尝试查看它的扩展。IIRC#$
或#@
生成字符,与标准#
生成字符串文字相同。@
是。它被称为charizing操作符,似乎没有与GCC等价的操作符。
#define ID 'A'
#if ID == 'A'