Триграф (языки Си)
Триграф (в семействе языков Си) (англ. trigraph) — последовательность из трёх символов, первые два из которых — вопросительные знаки («??
»), а третий указывает на значение триграфа. Триграфы обрабатываются препроцессором C/C++.
Таблица триграфовПравить
Триграф | Эквивалентный символ |
---|---|
??= | # |
??/ | \ |
??' | ^ |
??( | [ |
??) | ] |
??! | | |
??< | { |
??> | } |
??- | ~ |
Комбинация трёх вопросительных знаков («???
») не является триграфом.
В реальности триграфы практически не используются. Некоторые компиляторы (например, gcc) даже выдают предупреждение при обработке триграфов.
ИсторияПравить
Причина появления триграфов заключается в том, что семибитная кодовая страница ISO/IEC 646, принятая в 1972 году и основанная на ASCII, отводила позиции символов «#$@[\]^`{|}~
» под национальные символы (дополнительные буквы и символы валют). Например, код { a[i]='\n'; }
немцы могли видеть как ä aÄiÜ='Ön'; ü
. Для замены отсутствующих скобок и были введены триграфы.
В Паскале с этой же целью используются диграфы: (. .) (* *)
вместо [] {}
.
В стандарте C++17 триграфы отменены[1][2]. Обещают отменить и в Си23.
Примеры неожиданного поведенияПравить
Далее приведены примеры использования триграфа «??/
», заменяемого на символ «\
». Символ «\
» является экранирующим для символа перевода строки.
// Will the next line be executed????????????????/
a++;
После замены «??/
» на «\
» код a++;
во 2-й строке будет считаться продолжением комментария, начатого в 1-й строке.
/??/
* A comment *??/
/
После замены «??/
» на «\
» указанный код будет эквивалентен коду
/* A comment */
Пример программыПравить
??=include <stdio.h> /* # */
int main(void)
??< /* { */
char n??(5??); /* [ and ] */
n??(4??) = '0' - (??-0 ??' 1 ??! 2); /* ~, ^ and | */
printf("%c??/n", n??(4??)); /* ??/ = \ */
return 0;
??>
См. такжеПравить
ПримечанияПравить
- ↑ «Removing trigraphs??! Архивная копия от 9 июля 2018 на Wayback Machine», N3981, Richard Smith, 2014-05-06; [1] Архивная копия от 8 сентября 2017 на Wayback Machine
- ↑ OpenNews: Утверждён стандарт C++17 (неопр.). opennet.ru. Дата обращения: 7 сентября 2017. Архивировано 8 сентября 2017 года.