c - 带有两个反斜杠的行如何欺骗 C 预处理器?

标签 c haskell c-preprocessor

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

The C preprocessor is intended to be used only with C, C++, and Objective-C source code. In the past, it has been abused as a general text processor. It will choke on input which does not obey C's lexical rules. For example, apostrophes will be interpreted as the beginning of character constants, and cause errors. Also, you cannot rely on it preserving characteristics of the input which are not significant to C-family languages. If a Makefile is preprocessed, all the hard tabs will be removed, and the Makefile will not work.

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

#ifdef __GLASGOW_HASKELL__
import GHC.Num
import GHC.Real
import GHC.List
import GHC.Base
#endif

infix 5 \\ -- comment to fool cpp

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

这个愚弄cpp的注释是如何工作的?看起来像是一个有趣的 hack,但我无法通过 google 搜索有关该主题的任何内容。在 Haskell 中,这一行声明了一个优先级为 5 的中缀运算符 \\-- 之后的所有文本都将被忽略。但是它对 C 预处理器有什么作用,它实际上是通过什么方式“被愚弄”的?

最佳答案

如果你简单地说:

infix 5 \\

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

infix 5 \foo.c:8:10: warning: backslash-newline at end of file

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

infix 5 \

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

infix 5 \\ -- comment

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

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

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

关于c - 带有两个反斜杠的行如何欺骗 C 预处理器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42181630/

相关文章:

c - 对齐陷阱: not handling instruction e1913f9f at [<80467364>]

不能包含这两个文件(WinSock2、Windows.h)

c - 指针的作用类似于局部变量,并且不会在函数中保留其修改

c# - 如何在 C# 中重新定义标准关键字的名称

c++ - 我对 Include Guards 有一些困惑

c++ - 将#includes 扩展为 C++ 的文本文件

c++ - 如何确保我的代码是 ansi C,不涉及 C++。是否可以设置像gcc这样的编译器在遇到C++的特性时提示错误?

haskell - 实现状态monad时的数据构造函数错误?

haskell - 在没有多余代码的情况下在 Haskell 中展开数据类型

haskell - nixOS + Haskell + 堆栈 + OpenGL + freeglut