* [PATCH] inttypes.h: imaxabs(3): Implement as a macro @ 2022-09-13 15:18 Alex Colomar 2022-09-13 15:28 ` Alejandro Colomar ` (2 more replies) 0 siblings, 3 replies; 13+ messages in thread From: Alex Colomar @ 2022-09-13 15:18 UTC (permalink / raw) To: libc-alpha; +Cc: Alex Colomar, Florian Weimer, JeanHeyd Meneide Functions using the [u]intmax_t types have a problem: ABI. The [u]intmax_t types were designed so that users could blindly use them to work with whatever is the biggest size for a given architecture. But this is problematic to implement. These days, ABI stability is very important, and programs compiled a specific version of glibc should continue working with newer glibc releases. Of course, that means that future glibc versions can't change the types of functions, or the functions would be incompatible. So, we cannot really change the (linker) signature of functions; not even of those using [u]intmax_t. A solution to that problem is to use macros, and not real functions. That way, the program really links against whatever function works with the compile-time maximum width type, be it long or long long, and the program will be bonded to the ABI of long or long long, but will know nothing about intmax_t. We still need a linker symbol with the name imaxabs(), for old programs linked against old glibc versions, and also for compatibility with an interpretation of the ISO C standard that says that imaxabs(3) is a function. But the standard knows nothing about ABI or a linker, so a macro that evaluates to a differently-named function is not a straight violation, but rather stepping through the line without crossing it, AFAIK. This implementation with C11 _Generic() is one that I used for the new _Generic(3) manual page. It allows treating the macro as a function, and to take pointers to it. And it allows to more easily understand the definition of the macro, without needing to parse the ifdefs. It makes it easier to parse with tools like grepc(1): $ grepc -k __PRI64_PREFIX inttypes.h inttypes.h:44:# define __PRI64_PREFIX "l" inttypes.h:47:# define __PRI64_PREFIX "ll" $ grepc -k imaxabs inttypes.h inttypes.h:290:#define imaxabs _Generic(INTMAX_C(0), long: labs, long long: llabs) If glibc can't use C11 features in public headers, then usual ifdefs could be used. Cc: Florian Weimer <fweimer@redhat.com> Cc: JeanHeyd Meneide <wg14@soasis.org> Signed-off-by: Alex Colomar <alx.manpages@gmail.com> --- Hi Florian, What do you think about using this implementation of imaxabs(3) in glibc? Is it valid according to ISO C and/or POSIX? It's been a long time since I last built and tested glibc from so I haven't tested this patch yet. I'll try more seriously when it has some chances of being accepted. Cheers, Alex stdlib/inttypes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/inttypes.h b/stdlib/inttypes.h index d550769f2a..eb20e416ac 100644 --- a/stdlib/inttypes.h +++ b/stdlib/inttypes.h @@ -287,7 +287,7 @@ typedef struct /* Compute absolute value of N. */ -extern intmax_t imaxabs (intmax_t __n) __THROW __attribute__ ((__const__)); +#define imaxabs _Generic(INTMAX_C(0), long: labs, long long: llabs) /* Return the `imaxdiv_t' representation of the value of NUMER over DENOM. */ extern imaxdiv_t imaxdiv (intmax_t __numer, intmax_t __denom) -- 2.37.2 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] inttypes.h: imaxabs(3): Implement as a macro 2022-09-13 15:18 [PATCH] inttypes.h: imaxabs(3): Implement as a macro Alex Colomar @ 2022-09-13 15:28 ` Alejandro Colomar 2022-09-13 15:34 ` Alejandro Colomar 2022-09-13 18:27 ` Joseph Myers 2 siblings, 0 replies; 13+ messages in thread From: Alejandro Colomar @ 2022-09-13 15:28 UTC (permalink / raw) To: libc-alpha; +Cc: Florian Weimer, JeanHeyd Meneide [-- Attachment #1.1: Type: text/plain, Size: 585 bytes --] On 9/13/22 17:18, Alex Colomar wrote: > @@ -287,7 +287,7 @@ typedef struct > > > /* Compute absolute value of N. */ > -extern intmax_t imaxabs (intmax_t __n) __THROW __attribute__ ((__const__)); > +#define imaxabs _Generic(INTMAX_C(0), long: labs, long long: llabs) Maybe we could add the case 'int: abs', in case ILP64 archs would want to use int for intmax_t. > > /* Return the `imaxdiv_t' representation of the value of NUMER over DENOM. */ > extern imaxdiv_t imaxdiv (intmax_t __numer, intmax_t __denom) -- <http://www.alejandro-colomar.es/> [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] inttypes.h: imaxabs(3): Implement as a macro 2022-09-13 15:18 [PATCH] inttypes.h: imaxabs(3): Implement as a macro Alex Colomar 2022-09-13 15:28 ` Alejandro Colomar @ 2022-09-13 15:34 ` Alejandro Colomar 2022-09-13 18:27 ` Joseph Myers 2 siblings, 0 replies; 13+ messages in thread From: Alejandro Colomar @ 2022-09-13 15:34 UTC (permalink / raw) To: libc-alpha; +Cc: Florian Weimer, JeanHeyd Meneide [-- Attachment #1.1: Type: text/plain, Size: 2567 bytes --] Hi Florian, On 9/13/22 17:18, Alex Colomar wrote: > Functions using the [u]intmax_t types have a problem: ABI. > > The [u]intmax_t types were designed so that users could blindly > use them to work with whatever is the biggest size for a given > architecture. But this is problematic to implement. These days, > ABI stability is very important, and programs compiled a specific > version of glibc should continue working with newer glibc > releases. Of course, that means that future glibc versions can't > change the types of functions, or the functions would be > incompatible. > > So, we cannot really change the (linker) signature of functions; > not even of those using [u]intmax_t. > > A solution to that problem is to use macros, and not real > functions. That way, the program really links against whatever > function works with the compile-time maximum width type, be it > long or long long, and the program will be bonded to the ABI of > long or long long, but will know nothing about intmax_t. > > We still need a linker symbol with the name imaxabs(), for old > programs linked against old glibc versions, and also for > compatibility with an interpretation of the ISO C standard that > says that imaxabs(3) is a function. But the standard knows > nothing about ABI or a linker, so a macro that evaluates to a > differently-named function is not a straight violation, but rather > stepping through the line without crossing it, AFAIK. > > This implementation with C11 _Generic() is one that I used for the > new _Generic(3) manual page. It allows treating the macro as a > function, and to take pointers to it. And it allows to more > easily understand the definition of the macro, without needing > to parse the ifdefs. It makes it easier to parse with tools like > grepc(1): > > $ grepc -k __PRI64_PREFIX inttypes.h > inttypes.h:44:# define __PRI64_PREFIX "l" > inttypes.h:47:# define __PRI64_PREFIX "ll" > $ grepc -k imaxabs inttypes.h > inttypes.h:290:#define imaxabs _Generic(INTMAX_C(0), long: labs, long long: llabs) > > If glibc can't use C11 features in public headers, then usual > ifdefs could be used. > > Cc: Florian Weimer <fweimer@redhat.com> > Cc: JeanHeyd Meneide <wg14@soasis.org> > Signed-off-by: Alex Colomar <alx.manpages@gmail.com> > --- My plan, if this is welcome, is to get rid of most traces of [u]intmax_t in the ABI, so I'd continue with similar patches for other functions and symbols. Cheers, Alex -- <http://www.alejandro-colomar.es/> [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] inttypes.h: imaxabs(3): Implement as a macro 2022-09-13 15:18 [PATCH] inttypes.h: imaxabs(3): Implement as a macro Alex Colomar 2022-09-13 15:28 ` Alejandro Colomar 2022-09-13 15:34 ` Alejandro Colomar @ 2022-09-13 18:27 ` Joseph Myers 2022-09-13 18:47 ` Paul Eggert 2022-09-13 22:43 ` Alejandro Colomar 2 siblings, 2 replies; 13+ messages in thread From: Joseph Myers @ 2022-09-13 18:27 UTC (permalink / raw) To: Alex Colomar; +Cc: libc-alpha, Florian Weimer, JeanHeyd Meneide On Tue, 13 Sep 2022, Alex Colomar via Libc-alpha wrote: > What do you think about using this implementation of imaxabs(3) in > glibc? Is it valid according to ISO C and/or POSIX? No. There has to be a prototype in the header for when #undef is used on the macro definition. Note that GCC expands imaxabs inline as a built-in function (unless using -std=c90 or -fno-builtin etc.). Note that C2x allows integer types wider than intmax_t in certain cases. So there is no standard obstacle to providing int128_t and uint128_t and having be fully integer types as defined in C2x, without needing to change intmax_t - although appropriate syntax would be needed for INT128_C and UINT128_C. (Changing intmax_t would be a pain because of the very large number of printf-like functions in glibc, all of whose ABIs involve intmax_t.) -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] inttypes.h: imaxabs(3): Implement as a macro 2022-09-13 18:27 ` Joseph Myers @ 2022-09-13 18:47 ` Paul Eggert 2022-09-13 19:30 ` Joseph Myers 2022-09-13 22:43 ` Alejandro Colomar 1 sibling, 1 reply; 13+ messages in thread From: Paul Eggert @ 2022-09-13 18:47 UTC (permalink / raw) To: Joseph Myers; +Cc: Florian Weimer, libc-alpha, JeanHeyd Meneide, Alex Colomar On 9/13/22 13:27, Joseph Myers wrote: > C2x allows integer types wider than intmax_t in certain cases.... > (Changing intmax_t would be a pain because of the very large > number of printf-like functions in glibc, all of whose ABIs involve > intmax_t.) It would indeed be a pain. However, the possibility of wider-than-intmax_t types is potentially even a much greater pain for user code. It's common, for example, for user code to have functions like this: int print_offset (off_t offset) { intmax_t off = offset; return printf ("%jd", off); } Unfortunately, code like this would not work if off_t were wider than intmax_t. This is fresh in my mind as I recently added code like the above to paxutils, replacing older, pre-C99 code that converted off_t to strings by hand. Was I mistaken? <https://git.savannah.gnu.org/cgit/paxutils.git/commit/?id=2bf63fcba72c4f4bc54a4caf53d7923c1f9f174f> Is it safe to assume that standard types like off_t are no wider than intmax_t? If so, this should be documented explicitly somewhere in the glibc manual. If not, user code would be in so much hurt that it really ought to be glibc's job to widen intmax_t to be at least as wide as standard types, as painful as that widening might be. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] inttypes.h: imaxabs(3): Implement as a macro 2022-09-13 18:47 ` Paul Eggert @ 2022-09-13 19:30 ` Joseph Myers 2022-09-13 20:59 ` Paul Eggert 0 siblings, 1 reply; 13+ messages in thread From: Joseph Myers @ 2022-09-13 19:30 UTC (permalink / raw) To: Paul Eggert; +Cc: Florian Weimer, Alex Colomar, libc-alpha, JeanHeyd Meneide On Tue, 13 Sep 2022, Paul Eggert via Libc-alpha wrote: > Is it safe to assume that standard types like off_t are no wider than > intmax_t? Standard C doesn't discuss off_t at all. Maybe whatever version of POSIX gets based on C2x should address that question. -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] inttypes.h: imaxabs(3): Implement as a macro 2022-09-13 19:30 ` Joseph Myers @ 2022-09-13 20:59 ` Paul Eggert 0 siblings, 0 replies; 13+ messages in thread From: Paul Eggert @ 2022-09-13 20:59 UTC (permalink / raw) To: Joseph Myers; +Cc: Florian Weimer, Alex Colomar, libc-alpha, JeanHeyd Meneide [-- Attachment #1: Type: text/plain, Size: 330 bytes --] On 9/13/22 14:30, Joseph Myers wrote: > Standard C doesn't discuss off_t at all. Maybe whatever version of POSIX > gets based on C2x should address that question. That would be a good idea. However, the glibc manual should discuss this regardless of whether POSIX addresses it. For now, how about the attached proposed patch? [-- Attachment #2: 0001-Document-ISO-C23-s-types-wider-than-intmax_t.patch --] [-- Type: text/x-patch, Size: 1998 bytes --] From 4acf0090cf31cbde99bb64d8024f5f4bc90a6296 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Tue, 13 Sep 2022 15:56:38 -0500 Subject: [PATCH] =?UTF-8?q?Document=20ISO=20C23=E2=80=99s=20types=20wider?= =?UTF-8?q?=20than=20intmax=5Ft?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manual/arith.texi | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/manual/arith.texi b/manual/arith.texi index edb9cfdafb..83f3e7607b 100644 --- a/manual/arith.texi +++ b/manual/arith.texi @@ -96,7 +96,8 @@ one of these: @item uint_fast64_t @end itemize -If you want an integer with the widest range possible on the platform on +If you want an integer that ordinarily has the widest range possible +on the platform on which it is being used, use one of the following. If you use these, you should write code that takes into account the variable size and range of the integer. @@ -106,6 +107,18 @@ of the integer. @item uintmax_t @end itemize +Draft @w{ISO C23} allows for signed integer types wider than @code{intmax_t}. +These include signed bit-precise integer types and extended integer +types that are wider than @code{long long} and that are referred by the +type definition for an exact width integer type. For example, if +@code{intmax_t} is equivalent to @code{long long} and is 64 bits, +the signed bit-precise integer type @code{_BitInt (128)} and the +typedef @code{int128_t}, if they exist, are wider than @code{intmax_t}. +However, @theglibc{} avoids wider-than-@code{intmax_t} types +and it is safe to convert to @code{intmax_t} any signed integer value +documented as being generated or used by @theglibc{}, and similarly +for @code{uintmax_t} and unsigned integer values. + @Theglibc{} also provides macros that tell you the maximum and minimum possible values for each integer data type. The macro names follow these examples: @code{INT32_MAX}, @code{UINT8_MAX}, -- 2.37.2 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] inttypes.h: imaxabs(3): Implement as a macro 2022-09-13 18:27 ` Joseph Myers 2022-09-13 18:47 ` Paul Eggert @ 2022-09-13 22:43 ` Alejandro Colomar 2022-09-13 22:56 ` Joseph Myers 1 sibling, 1 reply; 13+ messages in thread From: Alejandro Colomar @ 2022-09-13 22:43 UTC (permalink / raw) To: Joseph Myers, Paul Eggert; +Cc: libc-alpha, Florian Weimer, JeanHeyd Meneide [-- Attachment #1.1: Type: text/plain, Size: 6042 bytes --] Hi Joseph, Paul, On 9/13/22 20:27, Joseph Myers wrote: > On Tue, 13 Sep 2022, Alex Colomar via Libc-alpha wrote: > >> What do you think about using this implementation of imaxabs(3) in >> glibc? Is it valid according to ISO C and/or POSIX? > > No. There has to be a prototype in the header for when #undef is used on > the macro definition. Ahh, yes, C23::7.1.4/1 says that "Any function declared in a header may be *additionally* implemented as a function-like macro defined in the header" That additionally is what requires pedantically to provide a real function. Let me suggest that the standard is defective in its definition of imaxabs_t (and in general about any functions using intmax_t). It should note that they "can be implemented as macros", as it does with getc(3). Providing a prototype (and the corresponding function definition) for functions with intmax_t is the issue (or one of them; see below). > > Note that GCC expands imaxabs inline as a built-in function (unless using > -std=c90 or -fno-builtin etc.). I don't understand the process by which gcc expands builtins. How does exactly the suggested macro interfere with it? Is it because of the macro? Or because of _Generic()? > > Note that C2x allows integer types wider than intmax_t in certain cases. That is a workaround to the type being broken. The type can't widen, due to ABI issues; for some time, the compiler provided __int128 as a limbo extension that wouldn't be covered by intmax_t, and later ISO C just acknowledged the fact and reworded the definition of intmax_t to be less of "the widest type" and more or "a wide but not really widest type, so don't really trust it very much". Since the standard (and implementations) is kind of broken in this regard, my intention is to deviate from the standard the bare minimum to make this type what it really was meant to be from the beginning. > So there is no standard obstacle to providing int128_t and uint128_t and > having be fully integer types as defined in C2x, without needing to change > intmax_t Yeah, there may not be, but then, what good is intmax_t? The name suggests that it is what it is not. After acknowledging that, it's not better than some random type widest_ish_t. long long, for historic reasons, is guaranteed to be exactly as wide as intmax_t, with less issues. If there's no hope in intmax_t, we should just mark the type as obsolescent, and discard any idea of having a "widest" type at all. Working around it to keep it there, but keeping it useless is not something I'd be happy with. I think this would be enough reason to deviate from the standard, and let's call it a non-conforming extension that improves usability. Let's keep a linker definition for old code; but don't allow new code to link to anything with intmax_t in it. > - although appropriate syntax would be needed for INT128_C and > UINT128_C. Yes, that's an issue that we could easily fix if intmax_t disappears from the ABI completely. Then we could grow it arbitrarily without any concerns. > (Changing intmax_t would be a pain because of the very large > number of printf-like functions in glibc, all of whose ABIs involve > intmax_t.) Ahh, you anticipated part 2 of my plan. Deprecate "j", and add a new set of macros PRIdMAX and the like. This type has it deserved. But I know those macros aren't very well received, so it is just part 2. I'd justify macros here for the same reason that I justified defining the functions as macros: ABI. I don't see a way of doing this without macros. On 9/13/22 20:47, Paul Eggert wrote: > On 9/13/22 13:27, Joseph Myers wrote: > >> C2x allows integer types wider than intmax_t in certain cases.... >> (Changing intmax_t would be a pain because of the very large >> number of printf-like functions in glibc, all of whose ABIs involve >> intmax_t.) > > It would indeed be a pain. However, the possibility of > wider-than-intmax_t types is potentially even a much greater pain for > user code. Indeed. intmax_t is just broken as it is right now. > It's common, for example, for user code to have functions > like this: > > int > print_offset (off_t offset) > { > intmax_t off = offset; > return printf ("%jd", off); > } > > Unfortunately, code like this would not work if off_t were wider than > intmax_t. This is fresh in my mind as I recently added code like the > above to paxutils, replacing older, pre-C99 code that converted off_t to > strings by hand. Was I mistaken? Not so broken. It's good enough for that. intmax_t is (with some caveat) wide enough to work with all current system data types; that is, intmax_t is always 64 bits, AFAIK, since long long is 64 bits in all existing systems that I know, and intmax_t must be at least as wide as long long. And I don't know of any system data types longer than long long (that would be __int128, but no system data types use that underlying type). > <https://git.savannah.gnu.org/cgit/paxutils.git/commit/?id=2bf63fcba72c4f4bc54a4caf53d7923c1f9f174f> > > Is it safe to assume that standard types like off_t are no wider than > intmax_t? If so, this should be documented explicitly somewhere in the > glibc manual. If not, user code would be in so much hurt that it really > ought to be glibc's job to widen intmax_t to be at least as wide as > standard types, as painful as that widening might be. It is safe. But so is long long, which is easier to use. intmax_t is dead, if it must be defined to be exactly as wide as long long (except of course, for fresh architectures that can define it to be exactly __int128, but then have to write that in stone, and will have the same problem with a hypothetical __int256. intmax_t is to be wide-able, or it becomes DOA, IMO. Cheers, Alex -- <http://www.alejandro-colomar.es/> [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] inttypes.h: imaxabs(3): Implement as a macro 2022-09-13 22:43 ` Alejandro Colomar @ 2022-09-13 22:56 ` Joseph Myers 2022-09-13 23:43 ` Alejandro Colomar 0 siblings, 1 reply; 13+ messages in thread From: Joseph Myers @ 2022-09-13 22:56 UTC (permalink / raw) To: Alejandro Colomar Cc: Paul Eggert, libc-alpha, Florian Weimer, JeanHeyd Meneide On Tue, 13 Sep 2022, Alejandro Colomar wrote: > I don't understand the process by which gcc expands builtins. How does > exactly the suggested macro interfere with it? Is it because of the macro? > Or because of _Generic()? My point is that you already have to go out of your way to get a link-time reference to imaxabs - it will almost always have been expanded inline instead. Given that, your patch is adding extra complexity to address an issue that doesn't actually exist. > That is a workaround to the type being broken. The type can't widen, due to > ABI issues; for some time, the compiler provided __int128 as a limbo extension > that wouldn't be covered by intmax_t, and later ISO C just acknowledged the > fact and reworded the definition of intmax_t to be less of "the widest type" > and more or "a wide but not really widest type, so don't really trust it very > much". It is the type used for preprocessor arithmetic, for example. intmax_t was discussed at length in WG14, and while there was agreement on reducing its uses (hence the change to floating-point return types for fromfp functions, for example, see bug 28327), there was not agreement on any particular form of obsolescence. And it *is* useful in practice for printing types such as off_t or mode_t with no corresponding printf formats; those could just do with appropriate constraints to be no wider than intmax_t when a future POSIX revision is based on C2x. > If there's no hope in intmax_t, we should just mark the type as obsolescent, > and discard any idea of having a "widest" type at all. I don't think it's useful to try to rehash here discussions that were had at length in WG14. > Ahh, you anticipated part 2 of my plan. Deprecate "j", and add a new set of > macros PRIdMAX and the like. This type has it deserved. But I know those > macros aren't very well received, so it is just part 2. The actual direction is to move away from those macros (adding length modifiers for printing intN_t / int_leastN_t / int_fastN_t without needing to use such macros any more). -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] inttypes.h: imaxabs(3): Implement as a macro 2022-09-13 22:56 ` Joseph Myers @ 2022-09-13 23:43 ` Alejandro Colomar 2022-09-14 16:41 ` Joseph Myers 0 siblings, 1 reply; 13+ messages in thread From: Alejandro Colomar @ 2022-09-13 23:43 UTC (permalink / raw) To: Joseph Myers; +Cc: Paul Eggert, libc-alpha, Florian Weimer, JeanHeyd Meneide [-- Attachment #1.1: Type: text/plain, Size: 3769 bytes --] Hi Joseph, On 9/14/22 00:56, Joseph Myers wrote: > On Tue, 13 Sep 2022, Alejandro Colomar wrote: > >> I don't understand the process by which gcc expands builtins. How does >> exactly the suggested macro interfere with it? Is it because of the macro? >> Or because of _Generic()? > > My point is that you already have to go out of your way to get a link-time > reference to imaxabs - it will almost always have been expanded inline > instead. Given that, your patch is adding extra complexity to address an > issue that doesn't actually exist. Ahh, now I understand. So, kind of the situation with bzero(3) which is implemented in the compiler, and glibc doesn't support it because the compiler always transforms it to memcpy(3). Then, if there are still any references, glibc still needs to fix that, or if there are no references, glibc could just remove the function completely. However, imaxabs(3) was just the starting point, because it happened to be the function I chose to use at random. Other functions using the type may not be so commonly inlined. > >> That is a workaround to the type being broken. The type can't widen, due to >> ABI issues; for some time, the compiler provided __int128 as a limbo extension >> that wouldn't be covered by intmax_t, and later ISO C just acknowledged the >> fact and reworded the definition of intmax_t to be less of "the widest type" >> and more or "a wide but not really widest type, so don't really trust it very >> much". > > It is the type used for preprocessor arithmetic, for example. Yep. Happens to always coincide with long long though (not in rank, but in width), so not much would be lost by using long long. > > intmax_t was discussed at length in WG14, and while there was agreement on > reducing its uses (hence the change to floating-point return types for > fromfp functions, for example, see bug 28327), there was not agreement on > any particular form of obsolescence. And it *is* useful in practice for > printing types such as off_t or mode_t with no corresponding printf > formats; those could just do with appropriate constraints to be no wider > than intmax_t when a future POSIX revision is based on C2x. Yes, and yet the same can be said about long long. intmax_t is one less character (both in the type name, and in "j"), but apart from that, no much benefit. Do we really need a typedef for a type that is guaranteed to be as wide as any system data type (effectively that is long long)? It wasn't the original intention for intmax_t, AFAIK, and neither is necessary. I considered changing to long long in the man pages to keep it simple. > >> If there's no hope in intmax_t, we should just mark the type as obsolescent, >> and discard any idea of having a "widest" type at all. > > I don't think it's useful to try to rehash here discussions that were had > at length in WG14. Okay. > >> Ahh, you anticipated part 2 of my plan. Deprecate "j", and add a new set of >> macros PRIdMAX and the like. This type has it deserved. But I know those >> macros aren't very well received, so it is just part 2. > > The actual direction is to move away from those macros (adding length > modifiers for printing intN_t / int_leastN_t / int_fastN_t without needing > to use such macros any more). While for fixed-width types it makes sense to use fixed strings "w<N>", for variable-width types, it doesn't so much. Otherwise, the types are really fixed-width, as far as the ABI is concerned, even if they are not explicit-width. I think having a macro PRIdMAX could make sense. But of course it depends on the meaning of intmax_t. -- <http://www.alejandro-colomar.es/> [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] inttypes.h: imaxabs(3): Implement as a macro 2022-09-13 23:43 ` Alejandro Colomar @ 2022-09-14 16:41 ` Joseph Myers 2022-09-14 19:03 ` JeanHeyd Meneide 0 siblings, 1 reply; 13+ messages in thread From: Joseph Myers @ 2022-09-14 16:41 UTC (permalink / raw) To: Alejandro Colomar; +Cc: Florian Weimer, libc-alpha, JeanHeyd Meneide On Wed, 14 Sep 2022, Alejandro Colomar via Libc-alpha wrote: > > intmax_t was discussed at length in WG14, and while there was agreement on > > reducing its uses (hence the change to floating-point return types for > > fromfp functions, for example, see bug 28327), there was not agreement on > > any particular form of obsolescence. And it *is* useful in practice for > > printing types such as off_t or mode_t with no corresponding printf > > formats; those could just do with appropriate constraints to be no wider > > than intmax_t when a future POSIX revision is based on C2x. > > Yes, and yet the same can be said about long long. intmax_t is one less > character (both in the type name, and in "j"), but apart from that, no much > benefit. It provides a clearer statement of intent to readers of the code than long long does. As I noted in the WG14 discussions of a few proposed obsoletions, just because some language feature is not useful for *all* the things some people might like to be able to use it for isn't a reason for obsoletion when it's still useful for *some* of those things. -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] inttypes.h: imaxabs(3): Implement as a macro 2022-09-14 16:41 ` Joseph Myers @ 2022-09-14 19:03 ` JeanHeyd Meneide 2022-09-15 12:33 ` Alejandro (Alex) Colomar 0 siblings, 1 reply; 13+ messages in thread From: JeanHeyd Meneide @ 2022-09-14 19:03 UTC (permalink / raw) To: Joseph Myers Cc: Alejandro Colomar, Florian Weimer, libc-alpha, JeanHeyd Meneide Dear Alejandro, Joseph, On Wed, Sep 14, 2022 at 12:41 PM Joseph Myers <joseph@codesourcery.com> wrote: > > On Wed, 14 Sep 2022, Alejandro Colomar via Libc-alpha wrote: > > > > intmax_t was discussed at length in WG14, and while there was agreement on > > > reducing its uses (hence the change to floating-point return types for > > > fromfp functions, for example, see bug 28327), there was not agreement on > > > any particular form of obsolescence. And it *is* useful in practice for > > > printing types such as off_t or mode_t with no corresponding printf > > > formats; those could just do with appropriate constraints to be no wider > > > than intmax_t when a future POSIX revision is based on C2x. > > > > Yes, and yet the same can be said about long long. intmax_t is one less > > character (both in the type name, and in "j"), but apart from that, no much > > benefit. > > It provides a clearer statement of intent to readers of the code than long > long does. > > As I noted in the WG14 discussions of a few proposed obsoletions, just > because some language feature is not useful for *all* the things some > people might like to be able to use it for isn't a reason for obsoletion > when it's still useful for *some* of those things. I agree here. I have a proposal to fix this, based on the assembly labels and similar existing practice found on a lot of compilers, and based on what BSDs such as NetBSD have been using for 25+ years to provide ABI stability despite shifting architectures and types: https://thephd.dev/_vendor/future_cxx/papers/C%20-%20Transparent%20Aliases.html I would rather we not fall back to macros for all the reasons Joseph and others mentioned (the standard library #undef macro reason is also listed in the above-linked paper). I personally view the exemptions we made for the upcoming C2x (C23) standard as stop-gaps to allow important evolution and implementation work from, but not general-purpose solutions. I think transparent aliases is a generic solution to the problem and would achieve much of what we need to do, but it will not be in until C2y/C3a (the next revision of the C standard) if I work hard at it and polish the wording while surfacing implementations. I also found a few embedded folks who similarly suffered drawbacks because their platform's compiler could not deal with the asm("") labels for ABIs, and broke the entire build on their machine. So even for non-large systems, there's a real need for a language-level indirection mechanism that has all the same properties as normal functions. I hope that we can still make do with implementation extensions while I (and others?) work to make proper strides in implementation. And I apologize it took me this long to come up with these things; I certainly do wish I was "faster on the draw" to solving these problems, so to speak. Best Wishes, JeanHeyd ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] inttypes.h: imaxabs(3): Implement as a macro 2022-09-14 19:03 ` JeanHeyd Meneide @ 2022-09-15 12:33 ` Alejandro (Alex) Colomar 0 siblings, 0 replies; 13+ messages in thread From: Alejandro (Alex) Colomar @ 2022-09-15 12:33 UTC (permalink / raw) To: JeanHeyd Meneide, Joseph Myers; +Cc: Florian Weimer, libc-alpha [-- Attachment #1.1: Type: text/plain, Size: 6205 bytes --] Dear JeanHeyd, Joseph, On 9/14/22 21:03, JeanHeyd Meneide wrote: > Dear Alejandro, Joseph, > > On Wed, Sep 14, 2022 at 12:41 PM Joseph Myers <joseph@codesourcery.com> wrote: >> >> On Wed, 14 Sep 2022, Alejandro Colomar via Libc-alpha wrote: >> >>>> intmax_t was discussed at length in WG14, and while there was agreement on >>>> reducing its uses (hence the change to floating-point return types for >>>> fromfp functions, for example, see bug 28327), there was not agreement on >>>> any particular form of obsolescence. And it *is* useful in practice for >>>> printing types such as off_t or mode_t with no corresponding printf >>>> formats; those could just do with appropriate constraints to be no wider >>>> than intmax_t when a future POSIX revision is based on C2x. >>> >>> Yes, and yet the same can be said about long long. intmax_t is one less >>> character (both in the type name, and in "j"), but apart from that, no much >>> benefit. >> >> It provides a clearer statement of intent to readers of the code than long >> long does. >> >> As I noted in the WG14 discussions of a few proposed obsoletions, just >> because some language feature is not useful for *all* the things some >> people might like to be able to use it for isn't a reason for obsoletion >> when it's still useful for *some* of those things. Hmm, I guess that makes sense. > > > I agree here. I have a proposal to fix this, based on the > assembly labels and similar existing practice found on a lot of > compilers, and based on what BSDs such as NetBSD have been using for > 25+ years to provide ABI stability despite shifting architectures and > types: https://thephd.dev/_vendor/future_cxx/papers/C%20-%20Transparent%20Aliases.html It was a good read! Let me share some thoughts on it. > > I would rather we not fall back to macros for all the reasons > Joseph and others mentioned (the standard library #undef macro reason > is also listed in the above-linked paper). I personally view the > exemptions we made for the upcoming C2x (C23) standard as stop-gaps to > allow important evolution and implementation work from, but not > general-purpose solutions. I think transparent aliases is a generic > solution to the problem and would achieve much of what we need to do, > but it will not be in until C2y/C3a (the next revision of the C > standard) if I work hard at it and polish the wording while surfacing > implementations. I also found a few embedded folks who similarly > suffered drawbacks because their platform's compiler could not deal > with the asm("") labels for ABIs, and broke the entire build on their > machine. So even for non-large systems, there's a real need for a > language-level indirection mechanism that has all the same properties > as normal functions. I think macros can be used for this same purpose (but don't cry so fast; please continue reading ;). They effectively achieve the aliasing objective, with an already existing feature. The objection seems to be 7.1.4. As your N2970 paper says, 7.1.4 is there to make sure that users can "remove" the aliasing that macros may be doing, so that they make sure they call the exact function they are trying to call by using #undef. That's not really true, since compilers don't care how much you #undef things, but they'll use builtins whether you like it or not, unless you work hard enough on your compiler flags and maybe even asm() statements to work around that. But let's ignore compiler builtins. The objective of 7.1.4 was that users can avoid macros and make sure they call a function called foo() if they want. Keeping 7.1.4, but then adding _Alias is a bit of lying. _Alias, like a macro, will make user code call a function different from what they think: in neither case will the generated assembly code have traces of foo(), if it was defined or _Aliased to something else; and you cannot #undef an _Alias, so 7.1.4 becomes a bit irrelevant. Nevertheless, and even if macros can achieve what _Alias does in the same way, given that the 7.1.4 restrictions were lifted, either for all functions, or for specific ones, I do like _Alias. In the end, macros can achieve what typedef does, and we still have it, and I like it. It provides a bit more safety, by being a C feature, and not a cpp(1) one; we get more warnings and more restrictions, which are nice. In general I like the paper very much. I'd say that the part of the rationale that talks about 7.1.4 is a bit of a lie in the sense that I stated above, but that's not a big issue to me. The feature makes sense, and seems an improvement over the GNU attribute. The GNU C issue could be overcome through macros (again), so it wasn't as painful to use, but still those macros make clear the the interface was less than ideal. See what I used: #define ALX_ALIAS_DECLARATION(aka, original) \ [[gnu::copy(original)]] extern typeof(original) aka #define ALX_ALIAS_DEFINITION(aka, original) \ [[gnu::alias(#original)]] ALX_ALIAS_DECLARATION(aka, original) #define ALX_ALIAS_WEAK_DEF(aka, original) \ [[gnu::weak]] ALX_ALIAS_DEFINITION(aka, original) So, yeah, your paper makes a lot of sense to standardize this. About the naming, if I may give my opinion, _Alias (and the alias macro) seem quite nice. 'using' would also be nice if the feature is a strict subset of the C++ one, so that programmers know they are the same exact feature, just that C++ obviously can apply it to more contexts. > > I hope that we can still make do with implementation extensions > while I (and others?) work to make proper strides in implementation. > And I apologize it took me this long to come up with these things; I > certainly do wish I was "faster on the draw" to solving these > problems, so to speak. Time gives the opportunity to think it very well, so I don't see it as bad. Just knowing that it is in the process of being fixed makes me happy enough. :-) Cheers, Alex > > Best Wishes, > JeanHeyd -- <http://www.alejandro-colomar.es/> [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2022-09-15 12:33 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-09-13 15:18 [PATCH] inttypes.h: imaxabs(3): Implement as a macro Alex Colomar 2022-09-13 15:28 ` Alejandro Colomar 2022-09-13 15:34 ` Alejandro Colomar 2022-09-13 18:27 ` Joseph Myers 2022-09-13 18:47 ` Paul Eggert 2022-09-13 19:30 ` Joseph Myers 2022-09-13 20:59 ` Paul Eggert 2022-09-13 22:43 ` Alejandro Colomar 2022-09-13 22:56 ` Joseph Myers 2022-09-13 23:43 ` Alejandro Colomar 2022-09-14 16:41 ` Joseph Myers 2022-09-14 19:03 ` JeanHeyd Meneide 2022-09-15 12:33 ` Alejandro (Alex) Colomar
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).