在此链接 unsigned wchar_t
中typedef
编辑为WCHAR
. winnt.h
但我在我的 SDK或 mingw中找不到这种 typedef winnt.h
。
wchar_t
是签名还是未签名?
我在 C 语言中使用 WINAPI。
的签名wchar_t
是未指定的。该标准只说(3.9.1/5):
类型
wchar_t
应具有与其他整数类型之一相同的大小、符号和对齐要求 (3.11),称为其基础类型。
(相比之下,类型char16_t
和char32_t
是明确无符号的。)
请注意,类型的长度会因平台而异。
Windows 使用 UTF-16 并且 wchar_t 是 2 个字节。Linux 使用 4 字节的 wchar_t。
我只是在几个平台上进行了测试,没有进行优化。
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 ----
它打印0x00010EFF
。wchar_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 ----
它打印0x000000000EFF0000
。wchar_t
已签署。相应的汇编代码说,movq $-131072, -16(%rbp)
. 32 位0xFFFE0000
升级为 64 位有符号-131072
.
3) 与 2) 相同的代码,在 RedHat(版本未知)+ gcc 4.4.7 上:它再次打印0x000000000EFF0000
. wchar_t
已签署。
我既没有测试printf
's 的实现也没有测试 WinAPI 的WCHAR
定义,而是编译器内置wchar_t
类型的行为(没有关于它在任何头文件上的签名的规范)和 C-to-ASM 编译器引擎。
请注意,1) 和 3) 上的编译器由同一供应商提供,即 GNU 项目。答案肯定取决于平台。(有人会在 Visual C++ 上进行测试吗?)