Почему был изобретен wchar_t? - PullRequest
23 голосов
/ 23 октября 2009

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

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

Ответы [ 10 ]

17 голосов
/ 23 октября 2009

Зачем нужен wchar_t? Чем оно выше короткого (или __int16 или чего-то еще)?

В мире C ++ wchar_t - это его собственный тип (я думаю, что это 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.

17 голосов
/ 23 октября 2009

См. Википедия .

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

10 голосов
/ 23 октября 2009

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

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

8 голосов
/ 23 октября 2009

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

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

char name[] = "Bob";

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

int8 name[] = "Bob";

То же самое происходит с wchar_t и int16 .

6 голосов
/ 23 октября 2009

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

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

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

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

6 голосов
/ 23 октября 2009

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

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

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

4 голосов
/ 23 октября 2009

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

2 голосов
/ 24 октября 2009

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

Очевидно, что в c ++ 0x будет поддержка юникода, но с текущей скоростью, которая может никогда не произойти ...

2 голосов
/ 23 октября 2009

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

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

1 голос
/ 29 ноября 2010

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

#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 вредным? на этом сайте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...