什么是' \'实际上在C?

时间:2013-06-25 06:51:08

标签: c gcc c-preprocessor

据我所知{C}中的\只是附加下一行,好像没有换行符。

请考虑以下代码:

main(){\
return 0;
}

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

main(){return
       0;
}

而不是

main(){return 0;
}

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

3 个答案:

答案 0 :(得分:10)

来自K&R section A.12 Preprocessing

  

A.12.2线拼接

     

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

答案 1 :(得分:10)

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

我的OS X安装中的GCC 4.2.1给出了预期的结果,Clang也是如此。此外,在开头添加#define并使用

进行测试
#define main(){\
return 0;
}
main()

产生正确的结果

}
{return 0;

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

更新:根据GCC FAQ-E(或cpp命令的默认设置)尝试将输出令牌置于大致相同的视觉效果中作为输入令牌的位置。要获得“原始”输出,请同时指定-P。这解决了观察到的问题。

可能发生了什么:

  1. 在保留视觉外观时,未被空格分隔的标记保持在一起。
  2. 在识别上述空格之前发生线拼接。
  3. {return令牌被分组到同一个视觉块中。
  4. 0跟随一个空格,并在下一行的位置被正确记录。
  5. PLUG:如果这对您来说非常重要,我已经实现了my own preprocessor,正确实现了原始预处理和保留空白的“漂亮”模式。在讨论之后,我added将拼接线连接到保留的空白。但是,它并不是真正的独立工具。它是编译器框架的测试平台,恰好是一个完全兼容的C ++ 11预处理器库,恰好有一个微型命令行驱动程序。 (但错误信息与GCC相同,或者Clang,没有颜色。)

答案 2 :(得分:4)

无所谓:/令牌化器不会看到任何差异。 1

更新回复评论:

  

对于预处理器的预期输出应该是多少,似乎存在相当大的混淆。我的观点是期望/似乎/合理一目了然但实际上并不需要以这种方式指定输出有效。输出中存在的空白量与解析器无关。重要的是预处理器应该在解释它时将续行视为一行。

     

换句话说:预处理器不是文本转换工具,它是一种令牌操作工具。

如果对你很重要,你可能

  • 将预处理器用于C / C ++以外的其他内容
  • 将C ++代码视为文本,这是一种代码味道。 (脑海中浮现了libclang和各种不太完整的解析器库)。

1 (预处理器可以按照它认为合适的方式自由地实现指定的结果。您看到的结果可能是实现者实现此特定转换的最有效方式)< / p>