在GCC中,wchar_t有多大?

16

GCC支持 -fshort-wchar参数,可以将wchar_t从4字节切换到2字节。

如何在编译时检测wchar_t的大小,以便正确地映射到适当的utf-16或utf-32类型?直到c++0x发布并提供稳定的utf16_t和utf_32_t typedefs为止。

#if ?what_goes_here?
  typedef wchar_t Utf32;
  typedef unsigned short Utf16;
#else
  typedef wchar_t Utf16;
  typedef unsigned int Utf32;
#endif

2
不要这么做。wchar_t与Unicode没有任何关系。它是一个独立的类型,可以容纳所有支持的语言环境中最大扩展字符集的成员。如果您的平台仅支持ASCII,则sizeof(wchar_t)可以为1。这也意味着例如L'mötley crüe'不一定是Unicode字符串 - 它也可能是使用wchar_t存储的Latin-1字符串。 - Nordic Mainframe
11
这是最普遍没有帮助的评论。基于这个建议,我们应该在C++0x普及之前永远不尝试处理Utf编码的字符串。与此同时,我需要一组typedefs,适用于我支持的各种平台,将其映射到可以容纳所需数据的最合适的不同类型。 - Chris Becke
6个回答

14

您可以使用宏

__WCHAR_MAX__
__WCHAR_TYPE__

它们由gcc定义。您可以使用echo "" | gcc -E - -dM检查它们的值。

由于__WCHAR_TYPE__的值可以从int变化为short unsigned intlong int,因此我认为最好的测试方法是检查__WCHAR_MAX__是否大于2^16。

#if __WCHAR_MAX__ > 0x10000
  typedef ...
#endif

1
我将此标记为答案,因为它最接近我所寻找的内容。另一个答案中的模板魔法似乎是一种更聪明的方式,可以支持更多平台,而不需要了解大量特定于平台的宏。 - Chris Becke

13
template<int>
struct blah;

template<>
struct blah<4> {
  typedef wchar_t Utf32;
  typedef unsigned short Utf16;
};

template<>
struct blah<2> {
  typedef wchar_t Utf16;
  typedef unsigned int Utf32;
};

typedef blah<sizeof(wchar_t)>::Utf16 Utf16;
typedef blah<sizeof(wchar_t)>::Utf32 Utf32;

1
为什么您会假设无符号短整型是2个字节宽度,而无符号整型是4个字节,然后不简单地无条件地对它们进行typedef?您在半心半意地使用自己的假设... - etarion
@etarion:我只是简单地回答了这个问题。在C++中,wchar_t是一个独特的类型(我不确定C语言),而且OP(显然)想要使用它。 - Fred Nurk
这是一种非常聪明的使用C++避免#ifdef魔法的方法。话虽如此,它确实会污染全局命名空间。 - Chris Becke
3
你可以将“blah”(或utf_types :P)放在“detail”命名空间中,类似于Boost如何隐藏实现细节。希望整个内容(包括最后的Utf16 / 32 typedefs)也被封装在你的项目命名空间中。 - Fred Nurk

8
您可以使用标准宏:WCHAR_MAX
#include <wchar.h>
#if WCHAR_MAX > 0xFFFFu
// ...
#endif

WCHAR_MAX 宏是由ISO CISO C++标准定义的(参见:ISO/IEC 9899-7.18.3其他整数类型的限制和ISO/IEC 14882-C.2),因此您可以在几乎所有编译器上安全使用它。


1
如果WCHAR_MAX在ISO标准中定义,您可以在所有编译器上安全使用它(因为任何未定义WCHAR_MAX的内容,在技术上都不是C或C++编译器)。 - Clearer

4

大小取决于编译器标志-fshort-wchar:

g++ -E -dD -fshort-wchar -xc++ /dev/null | grep WCHAR
#define __WCHAR_TYPE__ short unsigned int
#define __WCHAR_MAX__ 0xffff
#define __WCHAR_MIN__ 0
#define __WCHAR_UNSIGNED__ 1
#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
#define __SIZEOF_WCHAR_T__ 2
#define __ARM_SIZEOF_WCHAR_T 4

2
作为Luther Blissett所说,wchar_t与Unicode是独立存在的两个不同事物。
如果你真的在谈论UTF-16,请注意有些Unicode字符映射到两个16位字(U+10000..U+10FFFF,虽然这些字符在西方国家/语言中很少使用)。

现在,在表情符号和类似物的范围内有大量的使用。 - Marc Kees

2
$ g++ -E -dD -xc++ /dev/null | grep WCHAR
#define __WCHAR_TYPE__ int
#define __WCHAR_MAX__ 2147483647
#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1)
#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
#define __SIZEOF_WCHAR_T__ 4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接