6

我有 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 个字节。

4

2 回答 2

5

你不能 - 没有 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”不一定为“a”(0x61)编码 unicode 代码点。因此,严格来说,这是编写字符串的唯一方法:

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

这太可怕了。

于 2010-11-09T11:56:47.590 回答
0

啊! 便携性的奇迹:-)

如果您有适用于所有平台的 C99 编译器,请使用int_least16_t, uint_least16_t, ... from <stdint.h>。大多数平台也定义int16_t,但它不需要存在(如果平台能够一次使用恰好 16 位,则int16_t必须定义 typedef)。

现在将所有字符串包装在数组中uint_least16_t并确保您的代码不期望值uint_least16_t在 65535 处包装...

于 2010-11-09T11:58:23.470 回答