Я видел строку C, которая выглядела так:
!ErrorHasOccured() ??!??! HandleError();
Он правильно скомпилирован и работает нормально. Кажется, что он проверяет, произошла ли ошибка, и если она есть, то обрабатывает ее. Но я не совсем уверен, что он на самом деле делает или как он это делает. Похоже, программист пытается выразить свои чувства по поводу ошибок.
Я никогда раньше не видел ??!??!
ни одного языка программирования, и я не могу найти документацию для него нигде. (Google не помогает с поисковыми терминами, как ??!??!
). Что это делает и как работает пример кода?
!ErrorHasOccurred() ??!???! HandleError();
собираетесь компилировать? Это??!
???
!
. Доказывает смысл?ErrorHasOccured() && HandleError()
себя. Это также, как это делает Луа.Ответы:
??!
это триграф, который переводится как|
. Так оно говорит:который из-за короткого замыкания эквивалентен:
Гуру недели (имеет дело с C ++, но актуально здесь), где я поднял это.
Возможное происхождение триграфов или, как указывает @DwB в комментариях, более вероятно из-за сложности EBCDIC (опять же). Эта дискуссия на форуме разработчиков IBM, похоже, подтверждает эту теорию.
Из ISO / IEC 9899: 1999 §5.2.1.1, сноска 12 (h / t @ Random832):
источник
if (ErrorHasOccured()) HandleError()
. К счастью, вы обычно сталкиваетесь с этой идиомой в perl-коде.ErrorHasOccurred() && HandleError();
: если вы привыкли к сценариям оболочки. :)Ну, почему это вообще существует, вероятно, отличается от того, почему оно существует в вашем примере.
Все началось полвека назад с перепрофилирования терминалов связи в качестве компьютерных пользовательских интерфейсов. В начальную эпоху Unix и C это был телетайп ASR-33.
Это устройство было медленным (10 cps), шумным и уродливым, и его представление набора символов ASCII закончилось на 0x5f, поэтому у него не было (посмотрите на рис.) Ни одного из ключей:
Триграфы были определены для решения конкретной проблемы. Идея заключалась в том, чтобы программы на C могли использовать подмножество ASCII, найденное на ASR-33, и в других средах, в которых отсутствуют высокие значения ASCII.
Тем не менее, люди, пишущие код на C почти по определению, имели современное оборудование, 1 так что я думаю: кто-то хвастается или развлекается, оставляя в коде какое-то пасхальное яйцо, которое вы сможете найти.
Это действительно сработало, это привело к чрезвычайно популярному вопросу SO.
ASR-33 телетайп
1. В этом отношении триграфы были придуманы комитетом ANSI, который впервые встретился после того, как C добился безудержного успеха, поэтому ни один из оригинальных кодов или кодеров C не использовал бы их.
источник
#
был заменен на£
. В других регионах, возможно, у «ASCII» не было фигурных скобок и т. Д.if (x || y) { a[i] = '\0'; }
выглядеть неif (x öö y) ä aÄiÅ = 'Ö0'; å
в той кодировке.Это C триграф .
??!
есть|
, так же??!??!
как и оператор||
источник
<iso646.h>
заголовочный файл.Как уже говорилось
??!??!
, по существу , два триграфы (??!
и??!
снова) mushed вместе , которые заменяются переведенный на||
, то есть логическое ИЛИ , препроцессором.Следующая таблица, содержащая каждый триграф, должна помочь устранить неоднозначность альтернативных комбинаций триграфов:
Источник: C: Справочное руководство 5-е издание
Таким образом, триграф, который выглядит как
??(??)
, в конечном итоге отобразится[]
,??(??)??(??)
будет заменен[][]
и т. Д., Вы получите идею.Так как триграфы заменяются во время предварительной обработки, вы можете использовать,
cpp
чтобы самостоятельно просмотреть вывод, используя глупуюtrigr.c
программу:и обрабатывать его с помощью:
Вы получите консольный вывод
Как вы можете заметить, опция
-trigraphs
должна быть указана, иначеcpp
будет выдано предупреждение; это указывает на то, что триграфы остались в прошлом и не представляют никакой современной ценности, кроме как сбивать с толку людей, которые могут столкнуться с ними .Что касается обоснования введения триграфов, то лучше понять, рассматривая раздел истории ИСО / МЭК 646 :
(акцент мой)
Таким образом, по существу, некоторые необходимые символы (те, для которых существует триграф) были заменены в определенных национальных вариантах. Это приводит к альтернативному представлению с использованием триграфов, состоящих из символов, которые все еще были в других вариантах.
источник