【问题标题】:wchar_t is unsigned or signedwchar_t 无符号或有符号
【发布时间】:2012-08-10 19:22:39
【问题描述】:

在这个link unsigned wchar_ttypedefed 作为WCHAR。但我在我的 SDK winnt.h 或 mingw winnt.h 中找不到这种 typedef。

wchar_t 是签名还是未签名?

我在 C 语言中使用 WINAPI。

【问题讨论】:

  • 我认为该页面不正确。当编译器没有内置的wchar_t 类型时,库从前 曾经使用unsigned short。猜猜unsigned 只是在更改为wchar_t 时错误地留在那里。
  • 签名或未签名,你不应该使用它。请参阅 utf8everywhere.org
  • @Pavel:一般来说,当然可以,但是当您需要编写胶水代码、编译器测试、调试器的字符串解码器或任何数量的其他有效用例时,您没有选择但使用wchar_t。一揽子绝对值往往不是很有帮助。

标签: c winapi unicode wchar-t


【解决方案1】:

wchar_t 的签名未指定。标准只说(3.9.1/5):

类型 wchar_t 应具有与称为其基础类型的其他整数类型之一相同的大小、符号和对齐要求 (3.11)。

(相比之下,char16_tchar32_t 类型是明确无符号的。)

【讨论】:

  • Windows API 似乎将其定义为无符号。
  • @netcoder:“未指定”并不意味着不允许任何人定义它。这只是意味着该标准不要求任何签名。
  • 是的,我知道标准是怎么说的,我也知道它是如何工作的。这个问题被标记为winapi,所以我认为这个额外的信息仍然有用。
  • @netcoder 是的,不过它很有用。谢谢。看看我帖子中的链接。
  • @user1317084:您的问题是关于 C,还是关于 WinAPI 如何实现 C 的某些实现定义的方面?如果你能澄清一下就好了。
【解决方案2】:

请注意,类型的长度会因平台而异。

Windows 使用 UTF-16,而 wchar_t 为 2 个字节。 Linux 使用 4 字节的 wchar_t。

【讨论】:

  • 在我见过的大多数 Linux 系统上,wchar_t 是 32 位类型,大概是用于 UTF-32 数据的。
  • 已修复。自从我使用 Unicode 以来已经有几年了 - 我想我记得 Linux 使用 UTF-8,但如果是这样,为什么有一个四字节的 wchar_t?
  • 大多数现代 Linux 系统确实正常使用 UTF-8。这就是char 的用途。 32 位 wchar_t 对于需要固定宽度编码的 UTF-32 很有用。
【解决方案3】:

我只是在几个平台上进行了测试,没有优化。

1) MinGW (32-bit) + gcc 3.4.4:
---- snip ----
#include<stdio.h>
#include<wchar.h>
const wchar_t BOM = 0xFEFF;
int main(void)
{
    int c = BOM;
    printf("0x%08X\n", c+0x1000);
    return 0;
}
---- snip ----

它打印0x00010EFFwchar_t 未签名。 相应的汇编代码为movzwl _BOM, %eax。不是movSwl,而是movZwl

2) FreeBSD 11.2 (64-bit) + clang 6.0.0:
---- snip ----
#include<stdio.h>
#include<wchar.h>
const wchar_t INVERTED_BOM = 0xFFFE0000;
int main(void)
{
     long long c = INVERTED_BOM;
     printf("0x%016llX\n", c+0x10000000LL);
     return 0;
}
---- snip ----

它打印0x000000000EFF0000wchar_t 已签名。 对应的汇编代码说,movq $-131072, -16(%rbp)。 32 位 0xFFFE0000 提升为 64 位签名 -131072

3) 与 2) 相同的代码,在 RedHat(版本未知)+ gcc 4.4.7 上:它再次打印 0x000000000EFF0000wchar_t 已签名。

我既没有测试printf 的实现也没有测试WinAPI 的WCHAR 定义,而是编译器内置wchar_t 类型的行为(没有关于它在任何头文件上的签名的规范)和C-to-ASM 编译器引擎.

请注意,1) 和 3) 上的编译器由同一供应商提供,即 GNU 项目。答案肯定取决于平台。 (有人会在 Visual C++ 上进行测试吗?)

【讨论】:

    猜你喜欢
    • 2018-08-12
    • 2015-12-27
    • 2013-03-27
    • 2019-03-22
    • 1970-01-01
    • 2015-02-24
    • 2013-02-04
    • 2019-01-15
    相关资源
    最近更新 更多