Подтвердить что ты не робот

Cryptic line "??!??!" в устаревшем коде

Я реорганизую старый очень старый старый устаревший код, который содержит ошибки и очень сомнительные методы, по крайней мере, для современных стандартов. Теперь я пробежал одну строку, которую я просто не могу расшифровать:

p и k имеют тип int *

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

Когда я увидел это, я не мог поверить своим глазам - я знаю оператор ?, но его синтаксис bool ? trueresult : falseresult, а оператор ?? не имеет смысла (ленивая оценка действительно не применима здесь), а не могу ли я найти ссылку этого таинственного оператора где угодно.

Было бы здорово, если бы кто-то пролил свет на этот вопрос.

4b9b3361

Ответ 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;