繁体   English   中英

wchar_t 无符号或有符号

[英]wchar_t is unsigned or signed

在此链接中, unsigned wchar_ttypedefWCHAR 但我在 SDK winnt.h或 mingw winnt.h中找不到这种 typedef。

wchar_t是有符号的还是无符号的?

我在 C 语言中使用 WINAPI。

wchar_t的符号是未指定的。 该标准只说(3.9.1/5):

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

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

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

Windows 使用 UTF-16 并且 wchar_t 是 2 个字节。 Linux 使用 4 字节的 wchar_t。

该标准可能没有指定wchar_t是有符号还是无符号,但 Microsoft 有。 即使您的非 Microsoft 编译器不同意,Windows API 也会使用/Zc:wchar_t (wchar_t Is Native Type)中的此定义:

Microsoft 将wchar_t实现为两字节无符号值。 它映射到 Microsoft 特定的本机类型__wchar_t

类型 WCHAR,而不是 wchar_t,在 MSDN 上定义如下:

   #if !defined(_NATIVE_WCHAR_T_DEFINED)
    typedef unsigned short WCHAR;
    #else
    typedef wchar_t WCHAR;
    #endif

https://docs.microsoft.com/en-us/windows/win32/extensible-storage-engine/wchar

所以你可以得出结论,它在 windows 上定义为无符号?

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

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的实现,也没有测试 WinAPI 的WCHAR定义,而是编译器内置wchar_t类型的行为(没有关于其在任何头文件上的签名的规范)和 C-to-ASM 编译器引擎。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM