According to the C11 standard, char32_t and char16_t are not part
authorschwarze <schwarze@openbsd.org>
Tue, 5 Sep 2023 23:16:01 +0000 (23:16 +0000)
committerschwarze <schwarze@openbsd.org>
Tue, 5 Sep 2023 23:16:01 +0000 (23:16 +0000)
of the C language but are part of the C library and have to be
declared in <uchar.h> - see paragraph 7.28.2.

In stark contrast, according to the C++11 standard, char32_t and char16_t
are part of the C++ language, namely, keywords - see paragraph 2.12.1.
Consequently, they must not be declared in a header file.

To resolve this vile contradiction, use the predefined macro __cplusplus
to find out which language is in use for the current compilation unit -
see C11 paragraph 6.10.8.3 and C++11 paragraph 16.8.1.

Reminded of the problem by naddy@.
OK naddy@ who tested in make build / make release.
Looks reasonable to millert@.

include/uchar.h

index 2ed5f2c..15f2a0e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uchar.h,v 1.1 2023/08/20 15:02:50 schwarze Exp $      */
+/*     $OpenBSD: uchar.h,v 1.2 2023/09/05 23:16:01 schwarze Exp $      */
 /*
  * Written by Ingo Schwarze <schwarze@openbsd.org>
  * and placed in the public domain on March 19, 2022.
@@ -23,8 +23,10 @@ typedef __size_t     size_t;
 #define __STDC_UTF_16__        1
 #define __STDC_UTF_32__        1
 
+#if !defined(__cplusplus) || __cplusplus < 201103L
 typedef __uint16_t     char16_t;
 typedef __uint32_t     char32_t;
+#endif
 
 __BEGIN_DECLS
 size_t mbrtoc16(char16_t * __restrict, const char * __restrict, size_t,