Изменения макроса _T () для символьных данных UNICODE - PullRequest
5 голосов
/ 09 ноября 2010

У меня есть приложение UNICODE, в котором мы используем _T (x), который определяется следующим образом.

#if defined(_UNICODE)
#define _T(x) L ##x
#else
#define _T(x) x
#endif

Я понимаю, что L определяется как wchar_t, который будет 4 байта на любой платформе.Пожалуйста, поправьте меня, если я ошибаюсь.Мое требование состоит в том, что мне нужно, чтобы L было 2 байта.Так что для взлома компилятора я начал использовать флаг -fshort-wchar gcc.Но теперь мне нужно переместить мое приложение в zSeries, где я не вижу эффекта флага -fshort-wchar на этой платформе.

Для того, чтобы я мог портировать свое приложение на zSeriesМне нужно изменить макрос _T () таким образом, чтобы даже после использования L ## x и без использования флага -fshort-wchar мне нужно было получить 2-байтовые данные широких символов. Может кто-нибудь сказать мне, как я могу изменить определениеL, так что я могу определить L как 2 байта всегда в моем приложении.

Ответы [ 2 ]

5 голосов
/ 09 ноября 2010

Вы не можете - не без поддержки c ++ 0x.c ++ 0x определяет следующие способы объявления строковых литералов:

  • "строка символов char в некоторых кодировках, определенных реализацией" - char
  • u8 "String of utf8 chars" - char
  • u "строка символов utf16" - char16_t
  • U "строка символов utf32" - char32_t
  • L "строка wchar_t в некоторых кодировках, определенных реализацией" - wchar_t

Пока широко не поддерживается c ++ 0x, единственный способ кодировать строку utf-16 кросс-платформенным способом - разбить ее на биты:

// make a char16_t type to stand in until msvc/gcc/etc supports
// c++0x utf string literals
#ifndef CHAR16_T_DEFINED
#define CHAR16_T_DEFINED
typedef unsigned short char16_t;
#endif

const char16_t strABC[] = { 'a', 'b', 'c', '\0' };
// the same declaration would work for a type that changes from 8 to 16 bits:

#ifdef _UNICODE
typedef char16_t TCHAR;
#else
typedef char TCHAR;
#endif
const TCHAR strABC2[] = { 'a', 'b', 'b', '\0' };

Макрос _T может доставлять товары только на платформах, где ширина wchar_t составляет 16 бит.И альтернатива все еще не является кроссплатформенной: кодирование char и wchar_t определяется реализацией, поэтому «a» не обязательно кодирует кодовую точку unicode для «a» (0x61).Таким образом, чтобы быть строго точным, это единственный способ написать строку:

const TCHAR strABC[] = { '\x61', '\x62', '\x63', '\0' };

Что просто ужасно.

0 голосов
/ 09 ноября 2010

Ах!Чудеса переносимости: -)

Если у вас есть компилятор C99 для всех ваших платформ, используйте int_least16_t, uint_least16_t, ... из <stdint.h>.Большинство платформ также определяют int16_t, но он не обязательно должен существовать (если платформа способна использовать ровно 16 битов одновременно, необходимо определить typedef int16_t).

Теперь оберните все строки вмассивы uint_least16_t и убедитесь, что ваш код не ожидает, что значения uint_least16_t будут перенесены на 65535 ...

...