我看到一行C看起来像这样:
!ErrorHasOccured() ??!??! HandleError();
它编译正确,似乎运行正常 . 看起来它正在检查是否发生了错误,如果有错误,它会处理它 . 但我不确定它在做什么或者它是如何做的 . 看起来程序员正试图表达他们对错误的看法 .
我之前从未见过 ??!??!
在任何编程语言中,我可以't find documentation for it anywhere. (Google doesn' t帮助搜索术语,如 ??!??!
) . 它做了什么以及代码示例如何工作?
4 回答
那么,为什么这一般存在可能与你的例子中存在的原因不同 .
这一切都始于半个世纪前,将硬拷贝通信终端重新用作计算机用户界面 . 在最初的Unix和C时代,那是ASR-33电传打字机 .
这个设备很慢(10 cps),噪音和丑陋,它的ASCII字符集视图以0x5f结束,因此它(仔细观察图片)没有任何键:
The trigraphs被定义为修复特定问题 . 我们的想法是,C程序可以使用ASR-33上的ASCII子集以及缺少高ASCII值的其他环境 .
然而,几乎按照定义编写C代码的人有现代设备1,所以我的猜测是:有人炫耀或自娱自乐,在代码中留下一种复活节彩蛋供你找 .
它确实有效,它导致了一个广受欢迎的SO问题 .
ASR-33电传打字机
1.就此而言,三角形是由ANSI委员会发明的,它在C成功后首次遇到,因此原始的C代码或编码器都不会使用它们 .
??!
是trigraph,转换为|
. 所以它说:由于短路,相当于:
Guru of the Week(处理C但在这里相关),我选择了这个 .
Possible origin of trigraphs或@DwB在评论中指出,由于EBCDIC很难(再次),因此更有可能 . This关于IBM developerworks董事会的讨论似乎支持这一理论 .
来自ISO / IEC 9899:1999§5.2.1.1,脚注12(h / t @ Random832):
这是一个C trigraph .
??!
是|
,所以??!??!
是运算符||
如前所述
??!??!
本质上是两个trigraphs(??!
和??!
再次)组合在一起,被预处理器替换为||
,即Logical OR .包含所有三字母的下图将有助于消除替代三字母组合的歧义:
(图片取自C:A参考手册第5版)
所以看起来像
??(??)
的三字符最终将映射到[]
,??(??)??(??)
将被[][]
替换,依此类推,你就明白了 .由于在预处理期间替换了三字符,您可以使用cpp来自己获取输出视图,使用愚蠢的
trigr.c
程序:并处理它:
你会得到一个控制台输出
您可以注意到,必须指定选项
-trigraphs
,否则cpp
将发出警告;这表明卦是如何成为过去的事物而且没有现代 Value ,除了混淆可能碰到它们的人 .至于引入三元组背后的基本原理,在查看ISO/IEC 646的历史部分时可以更好地理解:
(强调我的)
因此,从本质上讲,某些所需的角色(存在三角形的角色)在某些国家变体中被替换 . 这导致使用由其他变体仍然存在的字符组成的三字符的替代表示 .