Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么宏扩展有时会添加空间?_C++_C Preprocessor - Fatal编程技术网

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简洁地说,因为使用
#
的“转换为字符串”被定义为关心标记之间是否有空格。如果我将其转换为字符串呢?然后它的可见行为和转换为字符串似乎删除了空间在这种情况下,我将添加对该示例的分析到我的回答空白不是标记。