C++ 为什么宏扩展有时会添加空间?
如果我这样做:C++ 为什么宏扩展有时会添加空间?,c++,c-preprocessor,C++,C Preprocessor,如果我这样做: #define F a F/ #define F / F/ 它扩展到a/ 如果我这样做: #define F a F/ #define F / F/ 它扩展到/,中间有一个空格 但如果我将其转换为字符串并打印,则不会添加任何空格: #包括 #定义STR_IMPL(x)#x #定义STR(x)STR_IMPL(x) #定义F/ int main(){ 看跌期权(STR(F/)); } 为什么两者之间有一个空间,但只有一部分时间?在其他情况下是否允许添加更多空间?宏在令牌级
#define F a
F/
#define F /
F/
它扩展到a/
如果我这样做:
#define F a
F/
#define F /
F/
它扩展到/
,中间有一个空格
但如果我将其转换为字符串并打印,则不会添加任何空格:
#包括
#定义STR_IMPL(x)#x
#定义STR(x)STR_IMPL(x)
#定义F/
int main(){
看跌期权(STR(F/));
}
为什么两者之间有一个空间,但只有一部分时间?在其他情况下是否允许添加更多空间?宏在令牌级别工作。以字符串形式打印结果时会添加空格以消除歧义
F/
是两个令牌,F
和/
。宏扩展后,它仍然需要两个令牌,/
和/
。但如果将它们相邻打印,则会变成/
,这只是一个标记(注释)。因此,两者之间需要有一个空间
长话短说:是的,宏扩展可以添加空格,因为空格在宏操作的级别上无关紧要。语言规范是这样的,在较高的级别上:
- 将输入分解为一系列标记
- 在该令牌序列上运行预处理器(生成另一个令牌序列)
- 编译生成的令牌序列
使用
#define F/
和STR(F/)
分析示例:
首先请注意,#define F/
后跟换行符意味着F
被两个标记w/
替换(其中我使用w表示空白标记)
标记化后,STR(F/)
的预处理标记顺序为:
,STR
,(
,F
,/
)
- w、
,STR\u IMPL
,w,(
,/
,/
)
- w、
“//”
#
预处理运算符的定义包括删除前导空格。因此,令牌序列w,/
,/
变为“/”
,而不是“/”
F/
或两个斜杠之间在任何点上都没有空格。我相信这样做的目的是确保符号分开/
是注释,/
是运算符/
写入两次。在这两种情况下,插入的空白量都未指定。但是,宏扩展不允许开始或结束注释。我认为有一些预处理器不添加空格。要获得额外分数,请在#define F/
行中添加尾随空格,然后重复stringization@M.M前导空格和尾随空格不重要,对吗?嗯,他们可以在不需要的时候添加空格吗?第一个例子是否可以扩展到a/
?他们可以添加任意数量的空格,还是只添加一个?@AyxanHaqverdili-简短回答,是的。如果我将结果转换为字符串,为什么不添加空格@AyxanHaqverdili简洁地说,因为使用#
的“转换为字符串”被定义为关心标记之间是否有空格。如果我将其转换为字符串呢?然后它的可见行为和转换为字符串似乎删除了空间在这种情况下,我将添加对该示例的分析到我的回答空白不是标记。