From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp71.iad3b.emailsrvr.com (smtp71.iad3b.emailsrvr.com [146.20.161.71]) by sourceware.org (Postfix) with ESMTPS id 515AE3857428 for ; Fri, 25 Jun 2021 02:56:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 515AE3857428 X-Auth-ID: tom@honermann.net Received: by smtp1.relay.iad3b.emailsrvr.com (Authenticated sender: tom-AT-honermann.net) with ESMTPSA id B1FDE60072; Thu, 24 Jun 2021 22:56:51 -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: Jonathan Wakely , "libstdc++@gcc.gnu.org" References: <67864633-a933-98d5-4edc-eecdf50cbcf1@honermann.net> From: Tom Honermann Message-ID: <2dc4d83e-2d95-32e4-addf-e6177628c4b8@honermann.net> Date: Thu, 24 Jun 2021 22:56:51 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.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: 0325c154-6ff7-4c27-8003-7940e31991a4-1-1 X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, 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: Fri, 25 Jun 2021 02:56:53 -0000 On 6/24/21 3:39 PM, Jonathan Wakely wrote: > On Thu, 24 Jun 2021 at 20:35, Tom Honermann via Libstdc++ > wrote: >> 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. > We could just go with your patch for now, and see what happens when > other C libraries start to add the new functions. But if you are > willing to work on a revised patch with the extra conditions, that > would be good. I'm happy to do that; it isn't much effort. > >> 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. > Sounds good. > >> 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. > I did consider the -fno-char8_t case and decided I didn't care for > those people, but your suggestion allows it to work for them, without > making it _too_ much messier. Yup.  And I don't want to give those people more reasons for being unhappy with me ;) I'll follow up with a revised patch soon.  Thank you for the review! Tom.