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

StackOverflow https://stackoverflow.com/questions/1669448

  •  13-09-2019
  •  | 
  •  

Вопрос

Я создал новый проект со следующим сегментом кода:

char* strange = "(Strange??)";
cout << strange << endl;

в результате получается следующий результат:

(Странно]

Таким образом, переводя '??)' -> ']'

Отладка показывает, что мой строковый литерал char * на самом деле является этим значением, и это не потоковый перевод.Очевидно, что это не та последовательность метасимволов, которую я когда-либо видел.Возможно, какая-то последовательность символов в Юникоде или wide char?Однако я так не думаю...Я пытался отключить все связанные настройки проекта, но безрезультатно.

У кого-нибудь есть объяснение?

  • Поиск :'вопросительный знак, вопросительный знак, закрывающая фигурная скобка' строковый литерал c c ++
Это было полезно?

Решение

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

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

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

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

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

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

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

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

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

    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.

Это Триграф!

??) это триграф.

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

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

Это триграф.

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

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

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

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

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

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

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

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

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