神秘的线条"??!??!" 在遗留代码中

use*_*221 23 c c++ operators

我正在重构一些非常古老的遗留代码,这些代码充满了错误和非常可疑的做法,至少对于现代标准而言.现在我跑过一条线,我根本无法破译:

p并且k是类型int *

return p??!??!k?p?*p:sizeof(*k):0;
Run Code Online (Sandbox Code Playgroud)

当我看到它时,我无法相信自己的眼睛 - 我知道?运算符,但它的语法bool ? trueresult : falseresult??操作符都没有意义(懒惰的评估确实不适用于此处),我无法在任何地方找到该神秘运算符的引用.

如果有人对此事有所了解,那真的很酷.

Yu *_*Hao 36

它被称为Trigraph:

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

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

??=    #
??(    [
??/    \
??)    ]
??'    ^
??<    {
??!    |
??>    }
??-    ~
Run Code Online (Sandbox Code Playgroud)

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

所以在三角形替换之后,线return p??!??!k?p?*p:sizeof(*k):0;变成了

return p || k ? p ? *p : sizeof(*k) : 0
Run Code Online (Sandbox Code Playgroud)

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

return (p || k) ? (p ? (*p) : sizeof(*k)) : 0;
Run Code Online (Sandbox Code Playgroud)


Moh*_*oun 7

那行代码相当于:

return p || k? p? *p : sizeof(*k) : 0;
Run Code Online (Sandbox Code Playgroud)

或者更清楚:

return (p || k)? (p? (*p) : sizeof(*k)) : 0;
Run Code Online (Sandbox Code Playgroud)