Пунктуаторы
Есть в стандарте языка Си малозаметный пункт за номером 6.4.6 — Punctuators. Например, следующая программа на C корректна и будет работать.
??=include <stdio.h> int main(int argc, const char * argv??(??)) ??< printf("Trigraphs from %sn", __FILE__); return 0; ??>
Это безобразие — не особенность моего Apple LLVM 4.2, это часть стандарта. Разумеется, не без причины. Для некоторых терминалов часть символов недоступна, их нельзя ввести с клавиатуры или отобразить на экране. Наверняка еще где-то такие терминалы встречаются. Чтобы решить проблему совместимости, недостающие символы заменили тройками из доступных — триграфами. Не для всех компиляторов триграфы включены по-умолчанию, иногда требуется добавить ключ -trigraphs.
Символ # / ^ [ ] | { } ~ Триграф ??= ??/ ??' ??( ??) ??! ??< ??> ??-
Казалось бы, триграфы решают поставленную проблему. Не могу утверждать наверняка, но похоже, что триграфы показались кому-то длинными и неудобными, предложили замену — диграфы. Мне неясно, почему изначально использовалось три символа, а не сразу два. Оптимизация выглядит очевидной. Как бы то ни было диграфы есть и не требуют отдельного ключа в моем Apple LLVM 4.2.
Символ # [ ] { } Диграф %: <: :> <% %>
Помимо того, что код с триграфами и диграфами непривычно (неудобно) читать, если они включены по-умолчанию, то это может привести к некоторым неожиданным последствиям. Например, ? и / находятся на одной клавише. Одна опечатка и мы никогда не узнаем, кто подставил кролика Роджера, потому что следующая за комментарием строка тоже станет комментарием.
// Who Framed Roger Rabbit??/ printf("Judge Doom");
Участники конкурсов по запутыванию и распутыванию кода любят пунктуаторы, незнающего человека они здорово могут сбить с панталыку. Пунктуаторы совершенно нейтральны к C, они не создают двусмысленности с конструкциями языка. C++ добавит вам проблем, потому что в нем есть пространства имен и шаблоны. Я плохо знаю C++, но интернет говорит, что неоднозначности есть, что, например, компилятор Microsoft решает их так, как будто триграфов и диграфов не существует, а последние версии GCC напортив, выполняют замены. Знайте и будьте внимательны. Простые примеры можно найти в репозитории https://github.com/alexchernyy/punctuators
Комментарии
asd
вот именно за такие "навороты" - я не люблю Cxx. Порой, проще посмотреть в дизассемблере, что именно делает программа, даже, имея на руках исходники.