wchar_t is unsigned or signed

Viewed 6938

In this link unsigned wchar_t is typedefed as WCHAR. But I cant find this kind of typedef in my SDK winnt.h or mingw winnt.h.

wchar_t is signed or unsigned?

I am using WINAPIs in C language.

5 Answers

The standard may not specify whether wchar_t is signed or unsigned, but Microsoft does. Even if your non-Microsoft compiler disagrees, the Windows API will be using this definition from /Zc:wchar_t (wchar_t Is Native Type):

Microsoft implements wchar_t as a two-byte unsigned value. It maps to the Microsoft-specific native type __wchar_t.

I just tested on several platforms, with no optimisation.

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 ----

It prints 0x00010EFF. wchar_t is unsigned. Corresponding assembly code says movzwl _BOM, %eax. Not movSwl, but 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 ----

It prints 0x000000000EFF0000. wchar_t is signed. Corresponfing assembly code says, movq $-131072, -16(%rbp). The 32-bit 0xFFFE0000 is promoted to 64-bit signed -131072.

3) Same code as 2), on RedHat (version unknown) + gcc 4.4.7: It again prints 0x000000000EFF0000. wchar_t is signed.

I tested neither the printf's implementation nor WinAPI's WCHAR definition, but the behaviors of compiler-builtin wchar_t type (no specification about its signedness on any header file) and C-to-ASM compiler engine.

Note that the compilers on 1) and 3) are provided by the same vendor, namely the GNU Project. The answer definitely depends on platforms. (Would somebody test on Visual C++?)

Related