Требуется ли строка строки u8 в С++ 11 - программирование
Подтвердить что ты не робот

Требуется ли строка строки u8 в С++ 11

От Wikipedia:

В целях повышения поддержки Unicode в компиляторах С++ определение типа char было изменено, чтобы быть, по крайней мере, размером, необходимым для хранения восьмибитового кодирования UTF-8.

Мне интересно, что именно это означает для написания переносных приложений. Есть ли разница между написанием этого

const char[] str = "Test String";

или это?

const char[] str = u8"Test String";

Есть ли какая-либо причина не использовать последнюю для каждого строкового литерала в вашем коде?

Что происходит, если в TestString есть не-ASCII-символы?

4b9b3361

Ответ 1

Кодирование "Test String" - это системное кодирование, определяемое реализацией (узкое, возможно многобайтное).

Кодирование u8"Test String" всегда является UTF-8.

Примеры не страшно говорят. Если вы включили в строку некоторые литералы из Юникода (например, \U0010FFFF), вы всегда будете получать их (кодированные как UTF-8), но могут ли они быть выражены в системной кодировке, и если да, то какова их ценность будет, определяется реализацией.

Если это поможет, представьте, что вы создаете исходный код на машине EBCDIC. Тогда буквальная "тестовая строка" всегда кодируется EBCDIC в самом исходном файле, но массив u8 -initialized содержит кодированные значения UTF-8, тогда как первый массив содержит значения, закодированные EBCDIC.

Ответ 2

Вы цитируете Википедию:

В целях расширения поддержки Unicode в компиляторах C++ определение типа char было изменено так, чтобы оно было как минимум размером, необходимым для хранения восьмибитной кодировки UTF-8.

Ну, "для целей" не соответствует действительности. char всегда гарантированно должен быть не менее 8 битов, то есть CHAR_BIT всегда должен был быть ≥8, из-за диапазона, требуемого для char в стандарте C. Что (цитата C++ 11 §17.5.1.5/1) "включено" в стандарт C++.

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

Что касается эффекта буквального префикса u8, он

  • влияет на кодировку строки в исполняемом файле, но

  • к сожалению это не влияет на тип.

Таким образом, в обоих случаях "tørrfisk" и u8"tørrfisk" вы получаете char const[ n ]. Но в первом литерале кодировка - это то, что выбрано для компилятора, например, с латинским 1 (или Windows ANSI Western), что будет 8 байтов для символов плюс нуль-байт для размера массива 9. В то время как в последнем литерале кодировка гарантированно будет UTF-8, где "ø" будет кодироваться 2 или 3 байтами (я не помню точно), для немного большего размера массива.

Ответ 3

Компилятор выбирает естественную естественную кодировку для платформы. В типичных системах POSIX он, вероятно, будет выбирать ASCII и что-то возможно в зависимости от настройки среды для значений символов вне диапазона ASCII. На мэйнфреймах он, скорее всего, выберет EBCDIC. Сравнение полученных строк, например, из файлов или командной строки, вероятно, будет лучше всего работать с набором собственных символов. Однако при обработке файлов, явно кодированных с использованием UTF-8, вам, вероятно, лучше всего использовать строки u8"...".

Тем не менее, с недавними изменениями, касающимися кодировок символов, фундаментальное предположение о строковой обработке в C и С++ было нарушено: каждый внутренний объект символа (char, wchar_t и т.д.) использовался для представления одного символа. Это явно неверно для строки UTF-8, каждый объект символа просто представляет собой байт некоторого символа. В результате все строковые манипуляции, классификация символов и т.д. Функции не обязательно будут работать над этими строками. У нас нет хорошей библиотеки, выстроенной для работы с такими строками для включения в стандарт.

Ответ 4

Если для символа исполнения для компилятора установлено значение UTF-8, не имеет значения, используется ли u8 или нет, поскольку компилятор преобразует символы в UTF-8 в обоих случаев.

Однако, если набор символов выполнения компиляторов является кодовой страницей системы, отличной от UTF8 (по умолчанию, например, Visual С++), тогда символы без символов ASCII могут неправильно обрабатываться, если u8 опущен. Например, преобразование в широкие строки приведет к сбою, например. в VS15:

std::string narrowJapanese("スタークラフト");
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convertWindows;
std::wstring wide = convertWindows.from_bytes(narrowJapanese); // Unhandled C++ exception in xlocbuf.