【问题标题】:How big is wchar_t with GCC?GCC 的 wchar_t 有多大?
【发布时间】:2011-06-19 21:39:49
【问题描述】:

GCC 支持 -fshort-wchar 将 wchar_t 从 4 转换为两个字节。

在编译时检测 wchar_t 大小的最佳方法是什么,以便我可以将其正确映射到适当的 utf-16 或 utf-32 类型? 至少,在 c++0x 发布并为我们提供稳定的 utf16_t 和 utf_32_t 类型定义之前。

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

【问题讨论】:

  • 不要这样做。 wchar_t 与 unicode 无关。它是一种独特的类型,可以容纳所有支持的语言环境中最大扩展字符集的所有成员。如果您的平台仅支持 ASCII,则 sizeof(wchar_t) 可以为 1。这也意味着,例如,L'mötley crüe' 不一定 是一个 unicode 字符串 - 它也可以是一个拉丁文-1 使用 wchar_t 存储的字符串。
  • 这是有史以来最普遍无益的评论。根据该建议,在 C++0x 普遍发布之前,我们不应该尝试处理 Utf 编码的字符串。同时,对于我支持的平台,我需要一组 typedef,映射到可以保存所需数据的最合适的不同类型。

标签: c++ gcc macros


【解决方案1】:

你可以使用宏

__WCHAR_MAX__
__WCHAR_TYPE__

它们由 gcc 定义。你可以通过echo "" | gcc -E - -dM查看它们的值

由于__WCHAR_TYPE__ 的值可以从intshort unsigned intlong int 不等,因此最适合您的测试是恕我直言,检查__WCHAR_MAX__ 是否高于2^16。

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

【讨论】:

  • 我将此标记为答案,因为它最接近我正在寻找的内容。另一个答案中的模板魔法似乎是一种更聪明的方式来支持更多平台,而无需了解大量特定于平台的宏
【解决方案2】:
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;

【讨论】:

  • 为什么你会假设一个 unsigned short 是 2 个字节宽,一个 unsigned int 是 4 个字节,而不是简单地无条件地 typedef 它们?你在半心半意地使用你的假设......
  • @etarion:我只是回答了这个问题。 Wchar_t 是 C++ 中的一种独特类型(我不记得 C),并且 OP(显然)想要使用它。
  • 这是使用 c++ 避免#ifdef 魔法的一种非常聪明的方法。也就是说,它确实污染了全局命名空间。
  • @ChrisBecke:您可以将 blah(或 utf_types :P)放在“detail”命名空间中,类似于 Boost 隐藏实现细节的方式。希望整个内容(包括最后一个 Utf16/32 类型定义)也包含在您项目的命名空间中。
【解决方案3】:

您可以使用标准宏:WCHAR_MAX:

#include <wchar.h>
#if WCHAR_MAX > 0xFFFFu
// ...
#endif

WCHAR_MAX 宏由 ISO CISO C++ 标准定义(参见:ISO/IEC 9899 - 7.18.3 Limits of other integer types and ISO/IEC 14882 - C.2),因此您可以在几乎所有编译器上安全地使用它。

【讨论】:

  • 如果在 ISO 标准中定义了 WCHAR_MAX,您可以在 all 编译器上安全地使用它(因为任何未定义 WCHAR_MAX 的东西在技术上都不是C 也不是 C++ 编译器)。
【解决方案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

【讨论】:

    【解决方案5】:

    正如 Luther Blissett 所说,wchar_t 独立于 Unicode 存在 - 它们是两个不同的东西。

    如果您真的在谈论 UTF-16 - 请注意,有些 unicode 字符映射到两个 16 位字(U+10000..U+10FFFF,尽管这些在西方国家/语言中很少使用)。

    【讨论】:

    • 如今,表情符号等在该范围内的使用量很大。
    【解决方案6】:
    $ 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
    

    【讨论】:

      猜你喜欢
      • 2013-02-26
      • 2017-04-06
      • 2012-12-25
      • 2018-11-22
      • 2016-02-23
      • 1970-01-01
      • 2012-12-07
      • 2011-06-16
      • 1970-01-01
      相关资源
      最近更新 更多