Ответ 1
Цель состоит в том, что строка новой строки в строчном литерале строки сопоставляется с одним
'\n'
символ. Это намерение не выражается так четко, как оно
должно быть, что привело к некоторой путанице.
Цитаты относятся к стандарту ISO С++ 2011 года.
Во-первых, это свидетельство того, что оно сопоставляется с одним символом '\n'
.
В примечании в параграфе 2.14.5 [lex.string] говорится:
[Примечание. Новая строка исходного файла в строковом литерале приводит к new-line в результате выполнения строкового литерала. Предполагая, что нет пробел в начале строк в следующем примере, утверждение будет успешным:
const char *p = R"(a\
b
c)";
assert(std::strcmp(p, "a\\\nb\nc") == 0);
- примечание к концу]
Это ясно указывает, что новая строка сопоставляется с одним '\n'
персонаж. Он также соответствует наблюдаемому поведению g++ 6.2.0 и
clang++ 3.8.1 (тесты, выполненные в системе Linux с использованием исходных файлов с
Unix-стиль и конец строки в стиле Windows).
Учитывая четко сформулированное намерение в примечании и поведение двух популярные компиляторы, я бы с уверенностью полагался на это - хотя это было бы интересно увидеть, как другие компиляторы действительно справляются с этим.
Однако, буквальное чтение нормативной формулировки стандарт может легко привести к другому выводу или, по крайней мере, к некоторой неопределенности.
Раздел 2.5 [lex.pptoken], пункт 3, говорит (выделено мной):
Между начальным и окончательным символами двойной кавычки raw string, любые преобразования, выполняемые в фазах 1 и 2 (триграфы, универсальные имена символов и сращивание строк)возвращаются; эта реверсия должна применяться до любого d- char, r- char или идентифицировать скобки.
Фазы перевода указаны в 2.2 [lex.phases]. В фазе 1:
Изображения физического исходного файла отображаются в определяемый реализацией, базовому набору символов источника (ввод символов новой строки для индикаторов конца строки), если необходимо.
Если мы предположим, что отображение физических символов исходного файла на
базовый набор символов и введение новых символов
"трансформации", мы могли бы разумно заключить, что, например,
строка новой строки в середине строкового литерала в формате Windows
исходный файл должен быть эквивалентен последовательности \r\n
. (Я могу представить
что полезно для кода, специфичного для Windows.)
(Эта интерпретация приводит к проблемам с системами, в которых индикатор конца строки не является последовательностью символов, например где каждая строка представляет собой запись фиксированной ширины. Такие системы редки в эти дни.)
Как "Приветствия и hth. - Alf" ответ указывает, что есть открытый Отчет о дефектах для этого вопроса. Он был представлен в 2013 году и еще не был решена.
Лично я считаю, что корень путаницы - это слово "любое", (курсив добавлен как раньше):
Между начальным и конечным символами двойной кавычки string, любые преобразования, выполняемые в фазах 1 и 2 (триграфы, универсальные имена символов и сращивание строк); это реверсия должна применяться до любого d- char, r- char или разграничения скобки указаны.
Несомненно, отображение физических символов исходного файла в основной набор символов источника можно разумно подумать о как преобразование. Предложение в скобках "(триграфы, универсальные имена символов и сращивание линий) ", как представляется, указать, какие преобразования должны быть возвращены, но либо пытается изменить значение слова "преобразования", (который стандарт официально не определяет) или противоречит использованию слова "любой".
Я предлагаю изменить слово "любое" на "определенное" явное намерение гораздо яснее:
Между начальным и конечным символами двойной кавычки строка, некоторые преобразования, выполняемые в фазах 1 и 2 (триграфы, имена универсальных символов и линейное сращивание) возвращаются; это реверсия должна применяться до любого d- char, r- char или разграничения скобки указаны.
В этой формулировке было бы более ясно, что "триграфы, универсальные имена символов и линейное сращивание "являются единственными преобразования, которые должны быть возвращены. (Не все сделано в фазах перевода 1 и 2 возвращается только те конкретные перечисленные преобразования.)