26

我正在重构一些非常古老的遗留代码,这些代码充满了错误和非常有问题的做法,至少对于现代标准来说是这样。现在我遇到了一条我根本无法破译的线:

p并且k是类型int *

return p??!??!k?p?*p:sizeof(*k):0;

当我看到它时,我简直不敢相信自己的眼睛——我知道?运算符,但它的语法是bool ? trueresult : falseresult并且??运算符都没有意义(惰性求值实际上不适用于这里),我无法在任何地方找到那个神秘运算符的引用。

如果有人对这件事有所了解,那就太酷了。

4

2 回答 2

37

它被称为Trigraph

C11(ISO/IEC 9899:201x) §5.2.1.1 三字序列

在进行任何其他处理之前,以下三个字符的序列之一(称为三字符序列17))的每次出现都被相应的单个字符替换。

??=    #
??(    [
??/    \
??)    ]
??'    ^
??<    {
??!    |
??>    }
??-    ~

它也在 C++11(ISO/IEC 14882:2011) § 2.3 Trigraph 序列中

所以在三元组替换后,这条线return p??!??!k?p?*p:sizeof(*k):0;变成了

return p || k ? p ? *p : sizeof(*k) : 0

由于三元运算符的优先级相当低,它实际上是:

return (p || k) ? (p ? (*p) : sizeof(*k)) : 0;
于 2013-07-18T08:26:03.793 回答
8

那行代码相当于:

return p || k? p? *p : sizeof(*k) : 0;

或者更清楚:

return (p || k)? (p? (*p) : sizeof(*k)) : 0;
于 2013-07-18T08:28:09.590 回答