У меня есть код, эквивалентный следующему, чтобы распечатать короткую строку:
#include <iostream>
#include <string>
int main(int argc, const char* argv[])
{
std::string s = "finished??/not finished??";
std::cout << s << std::endl;
return 0;
}
Но вывод появляется через две строки и теряет некоторые символы:
finished
ot finished??
Но /n
не символ новой строки! Что происходит?
На первом этапе перевода (§2.2 / 1 ISO / IEC 14882: 2011 (E)), последовательности символов, известных как последовательности триграфа заменяются одиночными символами.
Триграфные последовательности (2.4) заменяются соответствующими односимвольными внутренними представлениями.
Одна из карт триграфов ??/
в \
, После первого этапа код эквивалентен:
#include <iostream>
#include <string>
int main(int argc, const char* argv[])
{
std::string s = "finished\not finished??";
std::cout << s << std::endl;
return 0;
}
В результате этапов предварительной обработки, "finished\not finished??"
анализируется как строковый литерал содержащий escape-последовательность \n
который представляет символ новой строки. Выходная строка поэтому: finished<NL>ot finished??
,
Чтобы избежать этого, вам нужно выбрать один из знаков вопроса как \?
, Это дает вам:
#include <iostream>
#include <string>
int main(int argc, const char* argv[])
{
std::string s = "finished?\?/not finished??";
std::cout << s << std::endl;
return 0;
}
Это позволяет избежать ??/
быть выбранным как триграф.
В gcc 4.1.2 я получаю это предупреждение:
cd / devserv-home / rspikol /
g ++ -g -o tz tz.C
tz.C: 6: 28: предупреждение: триграф ?? / игнорируется, используйте -trigraphs для включения
Компиляция завершена в среду, 3 октября 12:43:16
Таким образом, по умолчанию эта версия gcc не соответствует стандарту C ++.
@sftrabbit: В моей копии стандарта C ++ этот абзац равен 2.3 / 1.