wchar_t 无符号或有符号

Posted

技术标签:

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

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

wchar_t 是签名还是未签名?

我在 C 语言中使用 WINAPI。

【问题讨论】:

类似问题:***.com/questions/2395514/… 我认为该页面不正确。当编译器没有内置的wchar_t 类型时,库从前 曾经使用unsigned short。猜猜unsigned 只是在更改为wchar_t 时错误地留在那里。 签名或未签名,你不应该使用它。请参阅 utf8everywhere.org @Pavel:一般来说,当然可以,但是当您需要编写胶水代码、编译器测试、调试器的字符串解码器或任何数量的其他有效用例时,您没有选择但使用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++ 上进行测试吗?)

【讨论】:

以上是关于wchar_t 无符号或有符号的主要内容,如果未能解决你的问题,请参考以下文章

C++ 中的 LPWSTR、wchar_t* 和无符号短指针

注意:“无符号”说明符会更改 Visual Studio 中 wchar_t 类型的大小

Verilog -- 有符号与无符号运算

为啥无符号短(乘)无符号短转换为有符号整数? [复制]

有符号整数与无符号整数

Mysql数据类型