在C中实际上做了什么?

ban*_*run 9 c gcc c-preprocessor

据我所知,\在C中只是附加下一行,好像没有换行符.

请考虑以下代码:

main(){\
return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我看到预处理的代码(gcc -E)时,它会显示出来

main(){return
       0;
}
Run Code Online (Sandbox Code Playgroud)

并不是

main(){return 0;
}
Run Code Online (Sandbox Code Playgroud)

这种行为的原因是什么?另外,我如何获得我期望的代码?

jpw*_*jpw 10

来自K&R部分A.12预处理:

A.12.2线拼接

以反斜杠字符\结尾的行通过删除反斜杠和以下换行符来折叠.这在分成令牌之前发生.

  • @TobiMcNamobi:好的.但真正的问题似乎是"为什么我会看到这种特殊的行为?". (3认同)

Pot*_*ter 10

是的,您的预期结果是C和C++标准所要求的结果.反斜杠只是转义换行符,即删除反斜杠换行符序列.

我的OS X安装中的GCC 4.2.1给出了预期的结果,Clang也是如此.此外,添加#define到开头并测试

#define main(){\
return 0;
}
main()
Run Code Online (Sandbox Code Playgroud)

产生正确的结果

}
{return 0;
Run Code Online (Sandbox Code Playgroud)

也许gcc -E在预处理之后和输出之前进行一些额外的处理.在任何情况下,预处理器其余部分看到的换行似乎都在正确的位置.所以这是一个美容虫.

更新:根据GCC FAQ,-E(或cpp命令的默认设置)尝试将输出标记放在与输入标记大致相同的视觉位置.要获得"原始"输出,请同时指定-P.这解决了观察到的问题.

可能发生了什么:

  1. 在保持视觉外观时,未被空格分隔的标记保持在一起.
  2. 在为上述标识空间之前发生线拼接.
  3. {return令牌被分组到相同的视觉块.
  4. 0 跟随一个空间,并在下一行的位置得到适当注意.

PLUG:如果这对你真的很重要,我已经实现了我自己的预处理器,正确实现了原始预处理和保留空白的"漂亮"模式.在讨论之后,我线条拼接添加到保留的空白区域.但是,它并不是真正的独立工具.它是编译器框架的测试平台,恰好是一个完全兼容的C++ 11预处理器库,恰好有一个微型命令行驱动程序.(但错误消息与GCC相同,或者Clang,没有颜色.)

  • "你的预期结果是C和C++标准所要求的结果." - 完全没有 - 标准不要求实现输出C代码,并且他们对程序生成的C代码的格式一无所知."所以这是一个美容虫." - 它根本不是一个bug,因为没有指定gcc -E输出的格式,除了它将正确编译. (3认同)