Вопрос

Я видел линию C, которая выглядела так:

!ErrorHasOccured() ??!??! HandleError();

Он скомпилирован правильно и, кажется, работает нормально. Похоже, что это проверяет, произошла ли ошибка, и если она имеет, это обрабатывает ее. Но я не совсем уверен, что на самом деле это делает или как это делает это. Похоже, что программист пытается выразить свои чувства по поводу ошибок.

Я никогда не видел ??!??! Раньше на любом языке программирования, и я не могу найти документацию нигде. (Google не помогает с такими терминами поиска ??!??!) Что это делает и как работает образец кода?

Это было полезно?

Решение

??! это Триграф это переводится на |. Анкет Итак, говорит:

!ErrorHasOccured() || HandleError();

который из -за короткого замыкания эквивалентно:

if (ErrorHasOccured())
    HandleError();

Гуру недели (имеет дело с C ++, но актуально здесь), где я поднял это.

Возможное происхождение триграфы Или, как указывает @DWB в комментариях, более вероятно, что EBCDIC будет трудным (снова). Этот Обсуждение в совете директоров IBM DeveloperWorks, похоже, поддерживает эту теорию.

Из ISO/IEC 9899: 1999 §5.2.1.1, сноска 12 (H/T @random832):

Последовательности триграфа включают ввод символов, которые не определены в наборе инвариантного кода, как описано в ISO/IEC 646, который является подмножеством семибитного набора кодов ASCII США.

Другие советы

Ну, почему это существует в целом, вероятно, отличается от того, почему оно существует в вашем примере.

Все началось полвека назад с перепрофилирования хардкопийных терминалов в качестве пользовательских интерфейсов компьютера. В первоначальной эре Unix и C, которая была телетипом ASR-33.

Это устройство было медленным (10 CPS) и шумным и уродливым, и его взгляд на набор символов ASCII закончился на 0x5F, поэтому оно было (внимательно посмотрите на PIC) ни один из ключей:

{ | } ~ 

Триграфы были определены, чтобы решить конкретную проблему. Идея заключалась в том, что программы C могли использовать подмножество ASCII, найденное на ASR-33, а в других средах, пропущенных высокими значениями ASCII.

Ваш пример на самом деле два из ??!, каждое значение |, поэтому результат ||.

Тем не менее, люди, пишущие C, код, почти по определению имел современное оборудование,1 Итак, я предполагаю: кто -то хвастается или развлекает себя, оставив своего рода пасхальное яйцо в коде для вас.

Это, безусловно, сработало, это привело к дико популярному, так что вопрос.

ASR-33 Teletype

ASR-33 Телетип


1. В этом отношении триграфы были изобретены Комитетом ANSI, который впервые встретился после C стали безудержным успехом, поэтому ни один из исходных C -кода или кодеров не использовал бы их.

Это c Триграф. ??! является |, так ??!??! оператор ||

Как уже говорилось ??!??! по сути два Триграфы (??! а также ??! Снова) объединился, которые заменяются ||, т.е. логичный или, от препроцессора.

Следующая таблица, содержащая каждый триграф, должна помочь неоднозначному альтернативным комбинациям триграфа:

Trigraph   Replaces

??(        [
??)        ]
??<        {
??>        }
??/        \
??'        ^
??=        #
??!        |
??-        ~

Источник: C: Справочное руководство 5 -е издание

Итак, триграф, который выглядит как ??(??) в конечном итоге наметит на [], ??(??)??(??) будет заменен на [][] И так далее, вы поняли идею.

Поскольку триграфы заменяются во время предварительной обработки, вы могли бы использовать cpp Чтобы увидеть вывод самостоятельно, используя глупый trigr.c Программа:

void main(){ const char *s = "??!??!"; } 

и обрабатывая это с помощью:

cpp -trigraphs trigr.c 

Вы получите консоль

void main(){ const char *s = "||"; }

Как вы можете заметить, вариант -trigraphs должен быть указан или еще cpp выпустит предупреждение; Это указывает на то, как Триграфы ушли в прошлое и не имеют современной ценности, кроме как сбивают с толку людей, которые могут наткнуться на них.


Что касается обоснования введения триграфы. Раздел истории ISO/IEC 646:

ISO/IEC 646 и его предшественник ASCII (ANSI X3.4) в значительной степени одобрили существующую практику в отношении кодировки персонажей в телекоммуникационной отрасли.

Поскольку ASCII не предоставил ряд персонажей, необходимых для языков, кроме английского,, Был сделан ряд национальных вариантов, которые заменили несколько менее используемых персонажей необходимыми..

(акцент мой)

Итак, по сути, некоторые необходимые персонажи (для которых существует триграф) были заменены в определенных национальных вариантах. Это приводит к альтернативному представлению с использованием триграфов, состоящих из символов, которые все еще имели другие варианты.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top