【问题标题】:Making size_t and wchar_t portable?使 size_t 和 wchar_t 可移植?
【发布时间】:2010-10-06 21:30:15
【问题描述】:

据我了解,size_t 和 wchar_t 的表示完全是特定于平台/编译器的。例如,我读过 Linux 上的 wchar_t 现在通常是 32 位,但在 Windows 上是 16 位。有什么方法可以在我自己的代码中将它们标准化为设定的大小(int、long 等),同时仍然保持与两个平台上现有标准 C 库和函数的向后可比性?

我的目标本质上是对它们进行 typedef 之类的操作,以使它们具有固定的大小。在不破坏某些东西的情况下这可能吗?我应该这样做吗?有没有更好的办法?

更新:我想这样做的原因是我的字符串编码在 Windows 和 Linux 上都是一致的

谢谢!

【问题讨论】:

  • 用术语谈论一个矛盾:“将它们标准化为设定的大小(int、long 等)”使它们与直接使用 size_t 和 wchar_t 一样可变。
  • wchar_t 用于 C 与 C++ 之间存在巨大差异。您需要确定您要使用哪种语言。
  • 为我的目的标准化。我想知道我在两个平台上运行的代码使用相同大小的项目。
  • 其中一个要点是,您无需关心它们的表示形式或特定于平台的大小。为什么你的代码需要它们的大小相同?
  • 我想避免 Windows 的 UTF-16 与 Linux 的 UTF-32 的头痛

标签: c++ c size-t


【解决方案1】:

听起来您正在寻找 C99 和 C++0x 的 <stdint.h>/<cstdint> 标头。这定义了uint8_tint64_t 等类型。

如果您没有这些标头,您可以使用 Boost 的 cstdint.hpp

【讨论】:

    【解决方案2】:

    您不想重新定义这些类型。相反,您可以使用 int32_tint16_t(有符号的 32 位和 16 位)之类的 typedef,它们是 C 标准库中 <stdint.h> 的一部分。

    如果您使用 C++,C++0x 将添加 char16_tchar32_t,它们是用于 UTF-16 和 UTF-32 的新类型(不仅仅是整数类型的 typedef)。

    对于wchar_t,另一种选择是只使用像ICU 这样的库,它以独立于平台的方式实现Unicode。然后,您可以只使用 UChar 类型,它始终是 UTF-16;您仍然需要注意字节顺序。 ICU 还提供与 UChar (UTF-16) 之间的converters

    【讨论】:

    • 如果我创建一个 int32_t 'string' 它是否仍然适用于所有基于 wchar_t 的函数/方法?我想知道在所有平台上我的编码都是 UTF-32(例如)
    • @Tyler,没有。您必须确保传递给需要wchar_t 字符串的函数的任何内容都可以安全地转换为它。因此,例如,将指向 int32_t 的指针传递给 Windows wchar_t 函数将失败。
    • 在 ICU 中,您可以使用 u_strToWCS() 和 u_strFromWCS() 在 UChar 和您平台的 Unicode wchar_t 之间进行转换(假设 wchar_t 是 Unicode)。然后只需在任何地方使用 UChar* 作为您的字符串。 ICU 提供了大量函数来处理 UChar* 字符串。
    【解决方案3】:

    没有。尝试使用 typedef 来“修复”字符类型的根本问题是,您最终得到的东西在某些平台上与内置函数和宽字符文字一致,而在其他平台上则不然。

    如果你想要一个在所有平台上都相同的字符串格式,你可以选择一个大小和签名。您想要无符号的 8 位“字符”,还是有符号的 64 位“字符”?您可以在任何具有适当大小的整数类型的平台上使用它们(并非所有平台都可以)。但是,就语言而言,它们并不是真正的字符,所以不要指望能够在它们上调用strlenwcslen,或者对文字有很好的语法。字符串文字是(嗯,转换为)char*,而不是signed char*unsigned char*。宽字符串字面量是wchar_t*,相当于some 其他整数类型,但不一定是你想要的。

    因此,您必须选择一种编码,在内部使用该编码,定义您自己的所需字符串函数版本,实现它们,然后根据需要转换为/从平台的编码转换为接受字符串的非字符串函数。 utf-8 是一个不错的选择,因为大多数 C 字符串函数仍然“工作”,即使它们不完全正确,它们也会做一些相当有用的事情。

    【讨论】:

      【解决方案4】:

      wchar_t 可能会比 size_t 更粘。可以假设 size_t 的最大大小(例如 8 个字节)并在写入文件(或套接字)之前将所有变量转换为该大小。要记住的另一件事是,如果您尝试写入/读取某种二进制表示,您将遇到字节顺序问题。无论如何, wchar_t 可能代表一个系统上的 utf-32 编码(我相信 Linux 会这样做),并且可能代表另一个系统上的 UTF-16 编码(Windows 会这样做)。如果您尝试在平台之间创建标准格式,则必须解决所有这些问题。

      【讨论】:

        【解决方案5】:

        仅在内部使用 UTF-8,并在将参数传递给需要它的 Windows 函数时即时转换为 UTF-16。可能永远不需要 UTF-32。由于处理单个字符而不是字符串通常是错误的(在 Unicode 意义上),因此使用大写或规范化 UTF-8 字符串并不比处理 UTF-32 字符串更困难。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-10-02
          • 2017-03-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多