【问题标题】:Cryptic line "??!??!" in legacy code [duplicate]神秘的行“??!??!”在遗留代码中[重复]
【发布时间】:2013-07-17 02:21:06
【问题描述】:

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

pk 的类型为 int *

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

当我看到它时,我简直不敢相信自己的眼睛 - 我知道 ? 运算符,但它的语法是 bool ? trueresult : falseresult?? 运算符都没有意义(惰性求值确实不适用于这里),不是我能在任何地方找到那个神秘操作员的参考资料吗?

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

【问题讨论】:

  • 您使用的是哪个编译器?例如,gcc 默认忽略三元组。是的,这确实是非常非常古老的代码。
  • @devnull 这是 gcc 但它是用 Makefile 编译的。现在我知道了什么是三元组,我也知道为什么有一个 -trigraphs 标志传递给编译器;)
  • Trigraphs (??!) 是邪恶的;链式三元运算符 (??::) 也是邪恶的;将它们混合在同一行中太多了!
  • 这纯属垃圾。我现在也要去重复问题那里添加此评论。

标签: c++ c operators


【解决方案1】:

它叫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;

【讨论】:

    【解决方案2】:

    那行代码相当于:

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

    或者更清楚:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-10
      • 2010-09-09
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多