[PATCH v4 2/3] stdlib: Implement mbrtoc8(), c8rtomb(), and the char8_t typedef.

Tom Honermann tom@honermann.net
Fri Jul 22 17:00:16 GMT 2022


On 7/22/22 10:15 AM, Adhemerval Zanella Netto wrote:
>
> On 22/07/22 08:21, Adhemerval Zanella Netto wrote:
>>
>> On 22/07/22 02:24, Tom Honermann wrote:
>>> On 7/21/22 4:56 PM, Adhemerval Zanella Netto wrote:
>>>> On 21/07/22 17:51, Tom Honermann wrote:
>>>>> On 7/21/22 3:22 PM, Adhemerval Zanella Netto wrote:
>>>>>> On 20/07/22 13:47, Tom Honermann wrote:
>>>>>>> Confirmed that this issue can be easily reproduced outside the testsuite.
>>>>>>>
>>>>>>> $ cat t.cpp
>>>>>>> #include <uchar.h>
>>>>>>>
>>>>>>> $ g++ --version
>>>>>>> g++ (GCC) 13.0.0 20220720 (experimental)
>>>>>>> ...
>>>>>>>
>>>>>>> $ g++ -c -I/path/to/glibc-char8_t/include -std=c++17 -Werror=c++20-compat t.cpp
>>>>>>> In file included from t.cpp:1:
>>>>>>> /home/tom/products/glibc-char8_t/include/uchar.h:38:23: error: identifier ‘char8_t’ is a keyword in C++20 [-Werror=c++20-compat]
>>>>>>>       38 | typedef unsigned char char8_t;
>>>>>>>          |                       ^~~~~~~
>>>>>>> cc1plus: some warnings being treated as errors
>>>>>>>
>>>>>>> The char8_t typedef is currently guarded by:
>>>>>>>
>>>>>>> /* Declare the C2x char8_t typedef in C2x modes, but only if the C++
>>>>>>>      __cpp_char8_t feature test macro is not defined.  */
>>>>>>> #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
>>>>>>> /* Define the 8-bit character type.  */
>>>>>>> typedef unsigned char char8_t;
>>>>>>> #endif
>>>>>>>
>>>>>>> __GLIBC_USE (ISOC2X) evaluates to true because gcc unconditionally defines _GNU_SOURCE. I believe otherwise, C++17 mode would only (or should only) imply __GLIBC_USE (ISOC11).
>>>>>>>
>>>>>>> Regardless, it seems that directives should be added to suppress the diagnostic. I tried prototyping such a fix, but it doesn't seem to work for me. I don't understand why.
>>>>>> I have tried as well and I can't get to work either.  It would expect to work
>>>>>> as we have done bits/stdlib-bsearch.h, could it be a gcc issue?
>>>>> prereqYes, this appears to be a gcc issue. I spent some time looking at gcc source code, but didn't find anything obvious. I verified the same technique does work to suppress the similar warning issued for use of, e.g., constexpr, as an identifier when -Wc++11-compat is enabled. I found tests that exercise #pragma GCC diagnostic ignored "-Wc++-compat", but none for -Wc++20-compat (or -Wc++11-compat).
>>>>>
>>>>> Tom.
>>>>>
>>>> In any case I think the fix below is the correct way (in fact I don't see
>>>> another way so I am assuming a compiler issue here).
>>> I agree. I debugged gcc tonight and discovered what the problem was. I'll submit a patch to gcc.
>>>> We also need to avoid
>>>> declare the typedef for __cplusplus >= 202002L.
>>> The typedef is already avoided if the __cpp_char8_t feature test macro is defined (builtin char8_t support can be enabled in previous C++ standard modes via the -fchar8_t option).
>> If the compiler preprocessor defined for -std=c++20? I had the impression it is
>> enabled iff -fchar8_t is set.
> I realized now I did not write proper english, I meant to ask if gcc always define
> __cpp_char8_t for -std=c++20 and higher since I had the impression that the
> define is only active iff -fchar8_t is actively used.

English is hard :)

For gcc, clang, and MSVC, -std=c++20 (/std:c++20 for MSVC) implies 
-fchar8_t (/Zc:char8_t), but that feature can be disabled with 
-fno-char8_t (/Zc:char8_t-). For example:

$ gcc -E -dM -x c++ -std=c++17 /dev/null | grep __cpp_char8_t
$ gcc -E -dM -x c++ -std=c++17 -fchar8_t /dev/null | grep __cpp_char8_t
#define __cpp_char8_t 201811L
$ gcc -E -dM -x c++ -std=c++20 /dev/null | grep __cpp_char8_t
#define __cpp_char8_t 201811L
$ gcc -E -dM -x c++ -std=c++20 -fno-char8_t /dev/null | grep __cpp_char8_t

Tom.



More information about the Libc-alpha mailing list