From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp97.iad3a.emailsrvr.com (smtp97.iad3a.emailsrvr.com [173.203.187.97]) by sourceware.org (Postfix) with ESMTPS id CEDFD383B420 for ; Thu, 24 Jun 2021 19:35:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CEDFD383B420 X-Auth-ID: tom@honermann.net Received: by smtp37.relay.iad3a.emailsrvr.com (Authenticated sender: tom-AT-honermann.net) with ESMTPSA id 52CB95C4A; Thu, 24 Jun 2021 15:35:21 -0400 (EDT) Subject: Re: [PATCH] C++ P0482R6 char8_t: declare std::c8rtomb and std::mbrtoc8 if provided by the C library To: Jonathan Wakely Cc: "libstdc++@gcc.gnu.org" References: From: Tom Honermann Message-ID: <67864633-a933-98d5-4edc-eecdf50cbcf1@honermann.net> Date: Thu, 24 Jun 2021 15:35:21 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US X-Classification-ID: e2594032-812f-4687-823d-2bcf84a9650a-1-1 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00, BODY_8BITS, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 24 Jun 2021 19:35:25 -0000 On 6/23/21 1:27 PM, Jonathan Wakely wrote: > N.B. please CC gcc-patches as well when sending patches to this list. Ah, yes, I think you've reminded me of that before. > > On Mon, 7 Jun 2021 at 03:16, Tom Honermann via Libstdc++ > wrote: >> This patch completes implementation of the C++20 proposal P0482R6 [1] by >> adding declarations of std::c8rtomb() and std::mbrtoc8() if provided by >> the C library. >> >> Autoconf changes determine if the C library declares c8rtomb and mbrtoc8 >> at global scope when uchar.h is included and compiled with -fchar8_t; >> _GLIBCXX_USE_UCHAR_CHAR8_T is defined if so. The header >> re-declares these functions in the std namespace only if available and >> the C++20 __cpp_char8_t feature test macro is defined. > > Thanks, Tom. I'm surprised that there's no __cplusplus dependency > here. Some C libraries aren't going to declare these new functions > unconditionally, only for C2x and C++20 modes. Your new configure > check tests for them with -std=c++11 -fchar8_t (and the implicit > -D_GNU_SOURCE on GNU/Linux) which doesn't guarantee they'll be > available. > > This isn't a problem for your glibc patches, because you do: > > +#if defined _CHAR8_T_SOURCE || defined __cpp_char8_t > +# define __GLIBC_USE_CHAR8_T 1 > > But consider a hypothetical libc that only define the new functions > for C2x/C++20, ignoring the __cpp_char8_t set by -fchar8_t. For such a > libc the configure test using -std=c++11 -fchar8_t will fail, and > libstdc++ won't declare the functions in namespace std even though > they are in libc. > > Shouldn't the configure test use -std=c++20 instead to check that > they're available for C++20 mode, and then in guard the using > declarations for ::c8rtomb and ::mbrtoc8 with #if __cplusplus >= > 202002L ? > > That would mean they're not declared in pre-C++20 when using > -fchar8_t, but that seems a lesser problem than having them not > declared in C++20 when they are actually present in libc. Maybe to > solve that we need two configure macros (or one macro with multiple > values), one that says the new functions are available for C++20, and > another that says they are also available pre-C++20 if __cpp_char8_t > is defined. Then can do something like: > > #if (__cplusplus >= 202002 && _GLIBCXX_USE_UCHAR_CXX20) \ > || (__cpp_char8_t && _GLIBCXX_USE_UCHAR_CHAR8_T) > > Messy. Hmm. Yup, you hit all the points I struggled with when coming up with an initial solution.  In the end, I settled on use of the C++ feature test macro being the only solution that worked in all cases, but it does imply that C libraries consistently follow suit. Multiple probes seems like a reasonable option.  I think it is fair to assume that, if the declarations are present for -std=c++11 -fchar8_t, then they will also be present for later language standards.  So, if that probe fails, we can then probe again using just -std=c++20. The conditional above would encounter errors for -std=c++20 -fno-char8_t for libc libraries that condition the declarations on the feature test macro.  I think it is reasonable to only enable the std namespace declarations if the __cpp_char8_t feature test macro is defined. #if __cpp_char8_t \     && (_GLIBCXX_USE_UCHAR_CXX11_CHAR8_T\         || (__cplusplus >= 202002 &&_GLIBCXX_USE_UCHAR_CXX20)) Still messy, but I think this covers all the bases. Tom.