Cryptic line "??!??!" в устаревшем коде
Я реорганизую старый очень старый старый устаревший код, который содержит ошибки и очень сомнительные методы, по крайней мере, для современных стандартов. Теперь я пробежал одну строку, которую я просто не могу расшифровать:
p
и k
имеют тип int *
return p??!??!k?p?*p:sizeof(*k):0;
Когда я увидел это, я не мог поверить своим глазам - я знаю оператор ?
, но его синтаксис bool ? trueresult : falseresult
, а оператор ??
не имеет смысла (ленивая оценка действительно не применима здесь), а не могу ли я найти ссылку этого таинственного оператора где угодно.
Было бы здорово, если бы кто-то пролил свет на этот вопрос.
Ответы
Ответ 1
Он называется Trigraph:
C11 (ISO/IEC 9899: 201x) §5.2.1.1 Последовательности триграфа
Прежде чем произойдет какая-либо другая обработка, каждое вхождение одного из следующих последовательности из трех символов (называемые последовательностями триграфа17)) заменены на соответствующий одиночный символ.
??= #
??( [
??/ \
??) ]
??' ^
??< {
??! |
??> }
??- ~
Это также в С++ 11 (ISO/IEC 14882: 2011) § 2.3 Последовательности триграфа
Итак, после замены триграфа линия 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;