How are UTF strings literals interpreted in C?

Viewed 99

Say, I want to interpret(i.e. through stdout) a UTF32-encoded string: zß水, taking the examples found on cppreference.

With U prefix, it's straightforward:

printf("%ls",U"zß水")

However, it won't work unless an appropriate "locale" being set before print:

setlocale(LC_ALL, "XXX.UTF-8")

My simplified question is that, why should we use XXX.UTF-8 locale settings, instead of some others like XXX.UTF-32?


My confusion arises when I was testing the code below:

#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#include <uchar.h>

void test2() {
    char32_t w_str[] = U"zß水";

    printf("wchar width: %d\n", __WCHAR_WIDTH__);
    if(__STDC_UTF_32__) printf("confirmed: utf32 used.\n");

    printf("(with '   C' locale) wide string is interpreted as: ");
    /* set locale */ if (setlocale(LC_ALL, "C") == NULL) perror("setlocale");
    if (printf("[%ls]", w_str) == -1) { perror("            ERROR('C' locale)"); clearerr(stdout); }
    printf("\n");

    printf("(with 'utf8' locale) wide string is interpreted as: ");
    /* set locale */ if (setlocale(LC_ALL, "en_US.UTF-8") == NULL) perror("setlocale");
    if (printf("[%ls]", w_str) == -1) { perror("            ERROR('utf8' locale)"); clearerr(stdout); }
    printf("\n");
}

int main(){test2();}

Along with output:

# gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)

wchar width: 32
confirmed: utf32 used.
            ERROR('C' locale): Invalid or incomplete multibyte or wide character
(with '   C' locale) wide string is interpreted as: [
(with 'utf8' locale) wide string is interpreted as: [zß水]

According to C11-6.4.4.4-9:

Prefix : Corresponding Type
U : char32_t

and C11-6.10.8.2-1:

_ _ STDC_UTF_32 _ _ The integer constant 1, intended to indicate that values of type char32_t are UTF−32 encoded.

My complete question is that, I've already specified an exact UTF32 string literal (and I'm 100% certain that they are exactly UTF32 encoded, by checking the assembly output of the code listed above), isn't it more appropriate to use some locale settings like XXX.UTF-32? If not, then why XXX.UTF-8 is qualified to decode the UTF32 byte sequence?

0 Answers
Related