Почему был изобретен wchar_t?

Почему требуется wchar_t? Как он превосходит short (или __int16 или что-то еще)?

(Если это имеет значение: я живу в мире Windows. Я не знаю, что Linux делает для поддержки Unicode.)

Ответ 1

Почему нужен wchar_t? Как он превосходит короткий (или __int16 или что-то еще)?

В мире С++ wchar_t - это собственный тип (я думаю, что это a typedef в C), поэтому вы можете перегружать функции на основе этого. Например, это позволяет выводить широкие символы, а не выводить их числовое значение. В VC6, где wchar_t был всего лишь typedef для unsigned short, этот код

wchar_t wch = L'A'
std::wcout << wch;

выводит 65, потому что

std::ostream<wchar_t>::operator<<(unsigned short)

. В новых версиях VC wchar_t - это отдельный тип, поэтому

std::ostream<wchar_t>::operator<<(wchar_t)

вызывается A.

Ответ 2

См. Wikipedia.

В принципе, это переносимый тип для "текста" в текущей локали (с умляутами). Он предшествует Unicode и не решает много проблем, поэтому сегодня он в основном существует для обратной совместимости. Не используйте его, если вам не нужно.

Ответ 3

Причина в том, что a wchar_t по той же причине существует size_t или time_t - это абстракция, которая указывает, какой тип предназначен для представления, и позволяет реализациям выбирать базовый тип, который может представлять собой типа на конкретной платформе.

Обратите внимание, что wchar_t не обязательно должен быть 16-разрядным типом - есть платформы, где 32-разрядный тип.

Ответ 4

Обычно считается хорошей вещью, чтобы давать такие вещи, как типы значимых имен данных.

Что лучше, char или int8? Я думаю это:

char name[] = "Bob";

гораздо легче понять, чем это:

int8 name[] = "Bob";

Это то же самое с wchar_t и int16.

Ответ 5

Когда я прочитал соответствующие стандарты, похоже, что Microsoft сильно исправила это.

Моя управляющая страница для POSIX <stddef.h> говорит, что:

  • wchar_t: целочисленный тип, диапазон значений которого может представляют собой различные широкозначные коды для всех членов самого большого набора символов, указанного среди локали, поддерживаемые средой компиляции: null символ имеет значение 0 и каждый элемент переносимого набора символов имеет значение кода, равное его значение при использовании в качестве одиночного символа целочисленного символа постоянная.

Итак, 16 бит wchar_t недостаточно, если ваша платформа поддерживает Unicode. Каждый wchar_t должен быть отличным значением для персонажа. Поэтому wchar_t - это полезный способ работать на уровне символов текстов (после декодирования из многоуровневого языка, конечно), чтобы быть совершенно бесполезным на платформах Windows.

Ответ 6

wchar_t - это примитив для хранения и обработки символов юникода платформы. Его размер не всегда 16 бит. В Unix-системах wchar_t - 32 бит (возможно, пользователи unix с большей вероятностью будут использовать klingon charaters, что дополнительные биты используются для: -).

Это может создавать проблемы для переноса проектов, особенно если вы меняете wchar_t и короткие, или если вы меняете wchar_t и xerces 'XMLCh.

Поэтому наличие wchar_t как другого типа для короткого замыкания очень важно для написания кросс-платформенного кода. Очистка это была одна из самых сложных частей переноса нашего приложения на unix, а затем с VC6 на VC2005.

Ответ 7

Чтобы добавить комментарий к Aaron - в С++ 0x мы, наконец, получаем реальные Unicode char типы: char16_t и char32_t, а также строковые литералы Unicode.

Ответ 8

Он "превосходит" в некотором смысле, что он позволяет разделить контексты: вы используете wchar_t в контекстах символов (например, строки), и используете short в числовых контекстах (числах). Теперь компилятор может выполнить проверку типов, чтобы помочь вам поймать ситуации, когда вы ошибочно смешиваете один с другим, например, передайте абстрактный нестроковый массив short в функцию обработки строк.

Как сторона node (так как это был вопрос C), в С++ wchar_t вы можете перегружать функции независимо от short, т.е. снова предоставлять независимые перегрузки, которые работают со строками и числами (например).

Ответ 9

wchar_t немного похмелье от стандартизации уникода. К сожалению, это не очень полезно, потому что кодирование является специфичным для платформы (и для Solaris, специфичного для локали!), А ширина не указана. Кроме того, нет никаких гарантий того, что грани utf-8/16/32 codecvt будут доступны, или как вы будете обращаться к ним. В общем, это немного кошмар для портативного использования.

По-видимому, С++ 0x будет поддерживать юникод, но при нынешних темпах прогресса, которые могут никогда не произойти...

Ответ 10

За исключением небольшого японского меньшинства ISO 2022, wchar_t всегда будет unicode. Если вы действительно беспокоитесь, вы можете убедиться в этом во время компиляции:

#ifndef __STDC_ISO_10646__
#error "non-unicode wchar_t, unsupported system"
#endif

Иногда wchar_t - 16 бит UCS-2, иногда 32 бит UCS-4, так что? Просто используйте sizeof(wchar_t). wchar_t НЕ предназначен для отправки на диск или в сеть, он предназначен только для использования в памяти.

См. также Следует ли считать UTF-16 вредным? на этом сайте.