Триграф (языки Си)
Триграф (в семействе языков Си) (англ. trigraph) — последовательность из трёх символов, первые два из которых — вопросительные знаки («??»), а третий указывает на значение триграфа. Триграфы обрабатываются препроцессором C/C++.
Таблица триграфов
| Триграф | Эквивалентный символ |
|---|---|
| ??= | # |
| ??/ | \ |
| ??' | ^ |
| ??( | [ |
| ??) | ] |
| ??! | | |
| ??< | { |
| ??> | } |
| ??- | ~ |
Комбинация трёх вопросительных знаков («???») не является триграфом.
В реальности триграфы практически не используются. Некоторые компиляторы (например, gcc) даже выдают предупреждение при обработке триграфов.
История
Причина появления триграфов заключается в том, что семибитная кодовая страница ISO/IEC 646, принятая в 1972 году и основанная на ASCII, отводила позиции символов «#$@[\]^`{|}~» под национальные символы (дополнительные буквы и символы валют). Например, код { a[i]='\n'; } немцы могли видеть как ä aÄiÜ='Ön'; ü. Для замены отсутствующих скобок и были введены триграфы.
В Паскале с этой же целью используются диграфы: (. .) (* *) вместо [] {}.
Примеры неожиданного поведения
Далее приведены примеры использования триграфа «??/», заменяемого на символ «\». Символ «\» является экранирующим для символа перевода строки.
// 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??!», N3981, Richard Smith, 2014-05-06;
- OpenNews: Утверждён стандарт C++17. opennet.ru. Дата обращения: 7 сентября 2017.