Изменения макроса _T() для символьных данных UNICODE

У меня есть приложение 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-байтовый широкий символ data.Can кто-нибудь сказать мне, как я могу изменить определение L, чтобы я мог определить L, чтобы быть 2 байта всегда в моем приложении.

2 ответа

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

  • "строка символов char в некоторой кодировке, определенной реализацией" - char
  • u8 "Строка символов utf8" - 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' };

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

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

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

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

Другие вопросы по тегам