Неизвестный метасимвол в строковом литерале C/C++?

Здание, что @Alexander, сказанный об удалении себя как слушатель:

, Если нет некоторый неопровержимый довод не к, одна вещь, я учился от своих коллег, то, что вместо того, чтобы делать анонимного внутреннего Слушателя, и должным быть сохранить его в переменной, заставляют B реализовать Слушателя, и затем B может удалить себя, когда это должно с a.removeListener(this)

6
задан bdonlan 3 November 2009 в 19:17
поделиться

9 ответов

То, что вы видите, называется триграфом .

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

GCC игнорирует триграфы по умолчанию, потому что вряд ли кто-то использует их намеренно. Включите их с помощью параметра -trigraph или сообщите компилятору, чтобы он предупреждал вас о них с помощью параметра -Wtrigraphs .

Visual C ++ 2010 также отключает их по умолчанию и предлагает ] / Zc: триграфы для их включения. Я ничего не могу найти о способах их включения или отключения в предыдущих версиях.

17
ответ дан 8 December 2019 в 02:11
поделиться

Простой способ избежать неожиданности триграфа: разделить "??" строковый литерал пополам:

char* strange = "(Strange??)";
char* strange2 = "(Strange?" "?)";
/*                         ^^^ no punctuation */

Edit
gcc имеет возможность предупреждать о триграфах: -Wtrigraphs (также включено с -Wall )
end edit

Цитаты из Стандарта

    5.2.1.1 Trigraph sequences
1   Before any other processing takes place, each occurrence of one of the
    following sequences of three characters (called trigraph sequences13))
    is replaced with the corresponding single character.
           ??=      #               ??)      ]               ??!      |
           ??(      [               ??'      ^               ??>      }
           ??/      \               ??<      {               ??-      ~
    No other trigraph sequences exist. Each ? that does not begin one of
    the trigraphs listed above is not changed.
    5.1.1.2 Translation phases
1   The precedence among the syntax rules of translation is specified by
    the following phases.
         1.   Physical source file multibyte characters are mapped, in an
              implementation-defined manner, to the source character set
              (introducing new-line characters for end-of-line indicators)
              if necessary. Trigraph sequences are replaced by corresponding
              single-character internal representations.
6
ответ дан 8 December 2019 в 02:11
поделиться
5
ответ дан 8 December 2019 в 02:11
поделиться

??) представляет собой триграф .

4
ответ дан 8 December 2019 в 02:11
поделиться

Это поддержка триграфа . Вы можете предотвратить интерпретацию триграфа, экранировав любой из символов:

char* strange = "(Strange?\?)";
4
ответ дан 8 December 2019 в 02:11
поделиться

Триграфы - причина. Разговор о C в статье относится и к C ++

3
ответ дан 8 December 2019 в 02:11
поделиться

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

Вы можете решить проблему, используя '\?' escape-последовательность для '?' персонаж:

char* strange = "(Strange\?\?)";

Фактически, это причина этой escape-последовательности, которая несколько загадочна, если вы не знаете этих чертовых триграфов.

2
ответ дан 8 December 2019 в 02:11
поделиться

При попытке кросс-компиляции на GCC моя последовательность была принята как триграф :

Итак, все, что мне нужно сделать сейчас, это выяснить, как отключить это в проектах по умолчанию, поскольку я вижу только, что это создает проблемы для меня. (Я все равно использую раскладку клавиатуры для США)

По умолчанию GCC игнорирует, но выдает предупреждение, что гораздо более разумно и действительно является тем, что Visual Studio 2010 примет в качестве стандарта, насколько мне известно.

1
ответ дан 8 December 2019 в 02:11
поделиться
3
ответ дан 8 December 2019 в 02:11
поделиться