首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >带有两个反斜杠的代码行如何欺骗C预处理器?

带有两个反斜杠的代码行如何欺骗C预处理器?
EN

Stack Overflow用户
提问于 2017-02-12 05:49:16
回答 1查看 453关注 0票数 16

我决定查看一个标准的Haskell模块Data.List的源代码,并发现了一些有趣的东西。显然,代码首先是由C预处理器处理的,就像一堆#ifdef建议的那样,然后才由Haskell编译器编译。然而,正如documentation中指出的那样,C预处理器对不同于C本身的源代码并不是很友好

C预处理器仅用于C、C++和Objective-C源代码。在过去,它被滥用为一个通用的文本处理器。如果输入不符合C的词法规则,它将阻塞输入。例如,撇号将被解释为字符常量的开始,并导致错误。此外,您不能依赖它保留输入的特征,这些特征对C系列语言来说并不重要。如果对Makefile进行预处理,则将删除所有硬制选项卡,并且Makefile将不起作用。

但不知何故,Haskell代码仍然保留在C预处理下?可能这段代码给出了一个线索:

代码语言:javascript
复制
#ifdef __GLASGOW_HASKELL__
import GHC.Num
import GHC.Real
import GHC.List
import GHC.Base
#endif

infix 5 \\ -- comment to fool cpp

-- -----------------------------------------------------------------------------
-- List functions

这个comment to fool cpp是如何工作的?看起来像是一个有趣的黑客攻击,但我无法在谷歌上搜索任何关于这个主题的东西。在Haskell中,这一行声明了一个优先级为5的中缀操作符\\,并且忽略了--之后的所有文本。但是它用C预处理器做什么呢?它是如何被“愚弄”的呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-12 06:02:47

如果你简单地这样说:

代码语言:javascript
复制
infix 5 \\

当该行位于文件的末尾时,C预处理器会发出以下消息:

代码语言:javascript
复制
infix 5 \foo.c:8:10: warning: backslash-newline at end of file

如果它不在文件的末尾(感谢@commenter),它只会“吃掉”一个反斜杠(将其与下面的换行符相关联),并且Haskell端的输出是不正确的:

代码语言:javascript
复制
infix 5 \

但是如果你后来添加了一个Haskell类型的注释,Haskell会忽略它(显然!),这对于C预处理器来说不是问题,因为\不在行尾:

代码语言:javascript
复制
infix 5 \\ -- comment

cpp发出完全相同的文本,Haskell可以解析有趣的部分,去掉--`注释。

(请注意,它永远不是有效的C语言,但预处理器并不介意)

注意:如果你想用\结束你的C/C++ //注释行,这个问题是相似的:你不能不在下一行继续注释:不是你想要的。

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42181630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档