Character Types

In C++, char is not necessarily the same type as signed char, although on most platforms they are equivalent.

The C++ standard defines char, signed char, and unsigned char as three distinct integral types, each with its own range of representable values. The C++ standard does not specify whether char is signed or unsigned by default, which means that it is implementation-defined.

On most platforms, char is implemented as a signed type, and its range of representable values is the same as that of signed char. However, on some rare platforms, char may be implemented as an unsigned type, in which case it would have the same range of representable values as unsigned char.

So, while char and signed char are often the same type in C++, it is not guaranteed by the standard. To ensure portability of code that relies on the signedness of char, it is recommended to use signed char explicitly.

Issue with wchar_t

wchar_t is a character type in C++ that is used to represent wide characters. It was introduced into C++ with the C++98 standard. Many Windows API functions have a wide character version that takes wchar_t strings as arguments. The wide character version of these functions has a suffix of W added to the function name. For example, the function CreateFile() in the Windows API has a wide character version named CreateFileW().

The C++ standard specifies that a string literal with an L prefix creates a wide character string literal.

#include <windows.h>

int main()
{
    LPCWSTR fileName = L"C:\\example\\test.txt";
    HANDLE hFile = CreateFileW(fileName, 
                               GENERIC_READ, 
                               FILE_SHARE_READ, 
                               NULL, 
                               OPEN_EXISTING, 
                               FILE_ATTRIBUTE_NORMAL, 
                               NULL);

    if (hFile == INVALID_HANDLE_VALUE) {
        // Handle error
        return 1;
    }
    // Do something with the file handle
    CloseHandle(hFile);
    return 0;
}

The issue with wchar_t is that its size is implementation-defined, which means that it can vary across different systems and compilers. The C++ standard does not specify the size of wchar_t, leaving it up to the implementation to decide. For example, on Windows systems, wchar_t is 16 bits (2 bytes), while on Unix-like systems, it is typically 32 bits (4 bytes).

This lack of standardization has led to portability issues when writing cross-platform code. Code that relies on wchar_t may not work as expected when compiled on a different system with a different wchar_t size. This can result in problems with data alignment, byte order, and other issues that can cause the program to behave incorrectly.

To address this issue, the C++11 standard introduced new character types, char16_t and char32_t, which have fixed sizes of 16 and 32 bits, respectively. These types are recommended for use in portable code, rather than wchar_t.