public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* Re: [RFC] Add stdckdint.h header for C23
       [not found] ` <68578b43-939-1879-9676-2ea55249a2c5@codesourcery.com>
@ 2023-06-13  6:28   ` Jakub Jelinek
  2023-06-13 15:10     ` Joseph Myers
  2023-06-14  2:54     ` Paul Eggert
  0 siblings, 2 replies; 9+ messages in thread
From: Jakub Jelinek @ 2023-06-13  6:28 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Marek Polacek, gcc-patches, libc-alpha

On Mon, Jun 12, 2023 at 09:51:02PM +0000, Joseph Myers wrote:
> On Sat, 10 Jun 2023, Jakub Jelinek via Gcc-patches wrote:
> 
> > I have looked at gnulib stdckdint.h and they are full of workarounds
> > for various compilers, EDG doesn't do this, clang <= 14 can't multiply
> > __int128, ..., so I think the header belongs into the compiler rather
> > than C library, because it would be a nightmare to maintain it there.
> 
> While C2x only has type-generic macros in this header, there's a proposal 
> N2868 (which didn't get consensus for C2x but may come back for a future 
> standard version) for additional interfaces for structure types with a 
> sticky overflow flag, including some functions that are expected to be 
> defined with external linkage as usual for library functions.  So if that 
> gets adopted in future, we'd need to arrange to provide those library 
> functions with external linkage - which is mostly not something we do in 
> GCC, although there are a few atomic_* functions in libatomic in addition 
> to the __atomic_* functions underlying type-generic macros.

There is always the possibility to have the header co-owned by both
the compiler and C library, limits.h style.
Just 
#if __has_include_next(<stdckdint.h>)
# include_next <stdckdint.h>
#endif
perhaps guarded with some macro at the end of the GCC version and
do the same at the start of the glibc version again perhaps with some macro.
And leave the compiler specific part to the compiler (perhaps with some
fallback in the libc version if the compiler specific part is missing) and
have the library related part be provided by the C library?

But if you want it solely in glibc, I can withdraw my patch (though, perhaps
the 2 preparation patches, __typeof_unqual__ and __builtin_classify_type
(typeof (...)) could be still of help for it).

> > What I'm struggling with is enforcing the weird restrictions
> > C23 imposes on these.
> 
> It's not clear all those restrictions need to be enforced - this 
> definitely seems like a case of undefined behavior to provide useful 
> extension space, where for various of those restrictions there are unique 
> sensible semantics to provide if the types in question are supported.

So why does C2X say
Recommended practice
It is recommended to produce a diagnostic message if type2 or type3 are
not suitable integer types, or if *result is not a modifiable lvalue of
a suitable integer type.
?
Or is it meant that a suitable integer type doesn't need to be necessarily
one that is listed in the previous paragraph?
Perhaps the checking could be guarded on #ifdef __STRICT_ANSI__, sure...

	Jakub


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC] Add stdckdint.h header for C23
  2023-06-13  6:28   ` [RFC] Add stdckdint.h header for C23 Jakub Jelinek
@ 2023-06-13 15:10     ` Joseph Myers
  2023-06-13 15:20       ` Jakub Jelinek
  2023-06-14  2:54     ` Paul Eggert
  1 sibling, 1 reply; 9+ messages in thread
From: Joseph Myers @ 2023-06-13 15:10 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Marek Polacek, gcc-patches, libc-alpha

On Tue, 13 Jun 2023, Jakub Jelinek via Gcc-patches wrote:

> There is always the possibility to have the header co-owned by both
> the compiler and C library, limits.h style.
> Just 
> #if __has_include_next(<stdckdint.h>)
> # include_next <stdckdint.h>
> #endif
> perhaps guarded with some macro at the end of the GCC version and
> do the same at the start of the glibc version again perhaps with some macro.
> And leave the compiler specific part to the compiler (perhaps with some
> fallback in the libc version if the compiler specific part is missing) and
> have the library related part be provided by the C library?

This seems a reasonable approach.  If the structure types do make it into 
future standard versions, we'd need to work out exactly where the division 
is between compiler and library header responsibilities (where those 
pieces involving structure types but not library functions go, for 
example).  For operations using structure types with overflow flag we'd 
need also to work out to what extent it's appropriate to implement those 
purely in the header with _Generic versus adding new built-in functions or 
extending what the existing ones can do.

> > > What I'm struggling with is enforcing the weird restrictions
> > > C23 imposes on these.
> > 
> > It's not clear all those restrictions need to be enforced - this 
> > definitely seems like a case of undefined behavior to provide useful 
> > extension space, where for various of those restrictions there are unique 
> > sensible semantics to provide if the types in question are supported.
> 
> So why does C2X say
> Recommended practice
> It is recommended to produce a diagnostic message if type2 or type3 are
> not suitable integer types, or if *result is not a modifiable lvalue of
> a suitable integer type.
> ?
> Or is it meant that a suitable integer type doesn't need to be necessarily
> one that is listed in the previous paragraph?
> Perhaps the checking could be guarded on #ifdef __STRICT_ANSI__, sure...

Diagnostics are better than doing something completely random - but making 
it conditional when there are sensible semantics also makes sense.

It seems likely a future standard version will support these operations 
for bit-precise types, at least.  (Bit-precise types are generally tricky 
for type-generic operations; there's no standard way to select on them 
with _Generic beyond listing individual types with specific widths, and no 
standard way to determine the width of the bit-precise type of an 
argument.  So implementing some type-generic operations for such types may 
need new language extensions, prompting WG14 caution about requiring such 
support - but this also makes support for such types in standard 
type-generic macros in headers particularly valuable, precisely because 
they can't be implemented purely in user code using standard language 
features.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC] Add stdckdint.h header for C23
  2023-06-13 15:10     ` Joseph Myers
@ 2023-06-13 15:20       ` Jakub Jelinek
  2023-06-13 15:45         ` Joseph Myers
  0 siblings, 1 reply; 9+ messages in thread
From: Jakub Jelinek @ 2023-06-13 15:20 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Marek Polacek, gcc-patches, libc-alpha

On Tue, Jun 13, 2023 at 03:10:48PM +0000, Joseph Myers wrote:
> > So why does C2X say
> > Recommended practice
> > It is recommended to produce a diagnostic message if type2 or type3 are
> > not suitable integer types, or if *result is not a modifiable lvalue of
> > a suitable integer type.
> > ?
> > Or is it meant that a suitable integer type doesn't need to be necessarily
> > one that is listed in the previous paragraph?
> > Perhaps the checking could be guarded on #ifdef __STRICT_ANSI__, sure...
> 
> Diagnostics are better than doing something completely random - but making 
> it conditional when there are sensible semantics also makes sense.
> 
> It seems likely a future standard version will support these operations 
> for bit-precise types, at least.  (Bit-precise types are generally tricky 
> for type-generic operations; there's no standard way to select on them 
> with _Generic beyond listing individual types with specific widths, and no 
> standard way to determine the width of the bit-precise type of an 
> argument.  So implementing some type-generic operations for such types may 
> need new language extensions, prompting WG14 caution about requiring such 
> support - but this also makes support for such types in standard 
> type-generic macros in headers particularly valuable, precisely because 
> they can't be implemented purely in user code using standard language 
> features.)

Yeah, having say __builtin_{clz,ctz,ffs,popcount,parity} variants which would
be typegeneric and would allow say any normal integral or _BitInt type
(or just unsigned versions thereof?) would be useful.  Even without _BitInt
we have the problem that we don't have builtins for __uint128_t.

One question is if we should keep them UB on zero input or hardcode some particular
behavior for clz/ctz.  The backend defaults might not be appropriate, I
think if we'd make it non-UB, using the precision of the type would be
reasonable, whatever it is (__builtin_clzb ((unsigned _BitInt(126)) 0)
might be 126 etc.).

	Jakub


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC] Add stdckdint.h header for C23
  2023-06-13 15:20       ` Jakub Jelinek
@ 2023-06-13 15:45         ` Joseph Myers
  0 siblings, 0 replies; 9+ messages in thread
From: Joseph Myers @ 2023-06-13 15:45 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Marek Polacek, gcc-patches, libc-alpha

On Tue, 13 Jun 2023, Jakub Jelinek via Gcc-patches wrote:

> Yeah, having say __builtin_{clz,ctz,ffs,popcount,parity} variants which would
> be typegeneric and would allow say any normal integral or _BitInt type
> (or just unsigned versions thereof?) would be useful.  Even without _BitInt
> we have the problem that we don't have builtins for __uint128_t.
> 
> One question is if we should keep them UB on zero input or hardcode some particular
> behavior for clz/ctz.  The backend defaults might not be appropriate, I
> think if we'd make it non-UB, using the precision of the type would be
> reasonable, whatever it is (__builtin_clzb ((unsigned _BitInt(126)) 0)
> might be 126 etc.).

FWIW the C2x stdbit.h operations all have defined semantics on special 
cases, except for the stdc_bit_ceil operations (where there's an NB 
comment on CD2 to be considered at next week's WG14 meeting requesting 
defined semantics there as well).  They're also all for unsigned 
arguments.  (Note there are also NB comments requesting removal of some of 
the operations as duplicates or near-duplicates of others.)

The stdbit.h header does seem naturally to be something for libc, given 
that (a) it has a lot of functions, not just type-generic macros, and (b) 
the type-generic macros are generally easy to implement (at least for the 
types supported in the standard) in a way that doesn't depend on any 
compiler extensions (or even on _Generic, many of them can be implemented 
just to call the function for unsigned long long).  It makes sense in due 
course for GCC to know the names there (after any get removed) as built-in 
functions, but mapping in a header to existing __builtin_* is generally 
easy until then.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC] Add stdckdint.h header for C23
  2023-06-13  6:28   ` [RFC] Add stdckdint.h header for C23 Jakub Jelinek
  2023-06-13 15:10     ` Joseph Myers
@ 2023-06-14  2:54     ` Paul Eggert
  2023-06-14  6:49       ` Jakub Jelinek
                         ` (2 more replies)
  1 sibling, 3 replies; 9+ messages in thread
From: Paul Eggert @ 2023-06-14  2:54 UTC (permalink / raw)
  To: Jakub Jelinek, Joseph Myers; +Cc: Marek Polacek, gcc-patches, libc-alpha

On 6/12/23 23:28, Jakub Jelinek via Libc-alpha wrote:
> On Mon, Jun 12, 2023 at 09:51:02PM +0000, Joseph Myers wrote:
>> On Sat, 10 Jun 2023, Jakub Jelinek via Gcc-patches wrote:
>>
>>> I have looked at gnulib stdckdint.h and they are full of workarounds
>>> for various compilers, EDG doesn't do this, clang <= 14 can't multiply
>>> __int128, ..., so I think the header belongs into the compiler rather
>>> than C library, because it would be a nightmare to maintain it there.

I tend to agree. I don't see how to implement <stdckdint.h> in the C 
library, at least not for the C library's users.

It would be possible to implement <stdckdint.h> for C library internal 
use only, because then we could assume #include_next, and we could use 
the Gnulib implementation safely (that implementation is already present 
glibc internals, just under a different name). This could well be worth 
doing, because glibc internally needs ckd_add (or something equivalent) 
but glibc can't yet assume that it's built with GCC 14 (or whatever GCC 
version eventually supports <stdckdint.h>).


> There is always the possibility to have the header co-owned by both
> the compiler and C library, limits.h style.
> Just
> #if __has_include_next(<stdckdint.h>)
> # include_next <stdckdint.h>
> #endif

I don't see how you could implement __has_include_next(<stdckdint.h>) 
for arbitrary non-GCC compilers, which is what we'd need for glibc 
users. For glibc internals we can use "#include_next" more readily, 
since we assume a new-enough GCC. I.e. we could do something like this:

    #if 14 <= __GNUC__
    # include_next <stdckdint.h>
    #else
    # define ckd_add(r, a, b) INT_ADD_WRAPV (a, b, &(r))
    #endif

where INT_ADD_WRAPV is the already-existing glibc internal macro, and 
where we invoke ckd_add only with arguments free of side effects.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC] Add stdckdint.h header for C23
  2023-06-14  2:54     ` Paul Eggert
@ 2023-06-14  6:49       ` Jakub Jelinek
  2023-06-14 11:46       ` Florian Weimer
  2023-06-14 14:52       ` Joseph Myers
  2 siblings, 0 replies; 9+ messages in thread
From: Jakub Jelinek @ 2023-06-14  6:49 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Joseph Myers, Marek Polacek, gcc-patches, libc-alpha

On Tue, Jun 13, 2023 at 07:54:25PM -0700, Paul Eggert wrote:
> I don't see how you could implement __has_include_next(<stdckdint.h>) for
> arbitrary non-GCC compilers, which is what we'd need for glibc users. For
> glibc internals we can use "#include_next" more readily, since we assume a
> new-enough GCC. I.e. we could do something like this:

Indeed, limits.h uses
#if defined __GNUC__ && !defined _GCC_LIMITS_H_
/* `_GCC_LIMITS_H_' is what GCC's file defines.  */
# include_next <limits.h>
#endif

I'd just do:
#if defined (__has_include_next) && !defined (ckd_add)
# if __has_include_next (<stdckdint.h>)
#  include_next <stdckdint.h>
# endif
#endif

and then deal with the fallback (if the C library really needs one,
does it need to support a C23 feature in arbitrary compiler which
doesn't support C23?).
A fallback should start with using __builtin_{add,sub,mul}_overflow
without extra checking if compiler supports it, with or without
use of __has_builtin.  GCC 6 and later has __builtin_{add,sub,mul}_overflow,
only GCC 10 has __has_builtin, I think clang has added those shortly
after they were added in GCC 6 (though, __builtin_{add,sub,mul}_overflow_p
which has been added in GCC 7 wasn't added to clang).

	Jakub


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC] Add stdckdint.h header for C23
  2023-06-14  2:54     ` Paul Eggert
  2023-06-14  6:49       ` Jakub Jelinek
@ 2023-06-14 11:46       ` Florian Weimer
  2023-06-14 14:52       ` Joseph Myers
  2 siblings, 0 replies; 9+ messages in thread
From: Florian Weimer @ 2023-06-14 11:46 UTC (permalink / raw)
  To: Paul Eggert
  Cc: Jakub Jelinek, Joseph Myers, Marek Polacek, gcc-patches, libc-alpha

* Paul Eggert:

> I don't see how you could implement __has_include_next(<stdckdint.h>)
> for arbitrary non-GCC compilers, which is what we'd need for glibc
> users.

This is not a requirement for glibc in general.  For example, <math.h>
only works with compilers to which it has been ported.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC] Add stdckdint.h header for C23
  2023-06-14  2:54     ` Paul Eggert
  2023-06-14  6:49       ` Jakub Jelinek
  2023-06-14 11:46       ` Florian Weimer
@ 2023-06-14 14:52       ` Joseph Myers
  2023-06-14 15:50         ` Zack Weinberg
  2 siblings, 1 reply; 9+ messages in thread
From: Joseph Myers @ 2023-06-14 14:52 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Jakub Jelinek, Marek Polacek, gcc-patches, libc-alpha

On Tue, 13 Jun 2023, Paul Eggert wrote:

> > There is always the possibility to have the header co-owned by both
> > the compiler and C library, limits.h style.
> > Just
> > #if __has_include_next(<stdckdint.h>)
> > # include_next <stdckdint.h>
> > #endif
> 
> I don't see how you could implement __has_include_next(<stdckdint.h>) for
> arbitrary non-GCC compilers, which is what we'd need for glibc users. For
> glibc internals we can use "#include_next" more readily, since we assume a
> new-enough GCC. I.e. we could do something like this:

Given the possibility of library functions being included in <stdckdint.h> 
in future standard versions, it seems important to look at ways of 
splitting responsibility for the header between the compiler and library, 
whether with __has_include_next, or compiler version conditionals, or some 
other such variation.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC] Add stdckdint.h header for C23
  2023-06-14 14:52       ` Joseph Myers
@ 2023-06-14 15:50         ` Zack Weinberg
  0 siblings, 0 replies; 9+ messages in thread
From: Zack Weinberg @ 2023-06-14 15:50 UTC (permalink / raw)
  To: Joseph Myers, Paul Eggert
  Cc: Jakub Jelinek, Marek Polacek, gcc-patches, GNU libc development

On Wed, Jun 14, 2023, at 10:52 AM, Joseph Myers wrote:
> On Tue, 13 Jun 2023, Paul Eggert wrote:
>
>> > There is always the possibility to have the header co-owned by both
>> > the compiler and C library, limits.h style. Just
>> > #if __has_include_next(<stdckdint.h>)
>> > # include_next <stdckdint.h>
>> > #endif
>>
>> I don't see how you could implement
>> __has_include_next(<stdckdint.h>) for arbitrary non-GCC compilers,
>> which is what we'd need for glibc users. For glibc internals we can
>> use "#include_next" more readily, since we assume a new-enough GCC.
>> I.e. we could do something like this:
>
> Given the possibility of library functions being included in
> <stdckdint.h> in future standard versions, it seems important to look
> at ways of splitting responsibility for the header between the
> compiler and library, whether with __has_include_next, or compiler
> version conditionals, or some other such variation.

limits.h is a horrible mess, with both the compiler and the library
trying to get the last word, and I don't think we should take it as a
model. I suggest a better model is GCC 12's stdint.h, where the compiler
provides "stdint-gcc.h" that's used *only* in freestanding mode, and a
wrapper header that defers to the C library (using #include_next, which
is safe in GCC-provided headers) when __STDC_HOSTED__ is defined;
meanwhile, glibc's stdint.h doesn't look for compiler-provided headers
at all.

In this case it sounds like glibc needs the compiler to provide some of
the definitions, and I suggest this should be done via private predefined
macros, in the mode of __INTx_TYPE__ and friends.

zw

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-06-14 15:51 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <ZIRSdNvz+pbiUQLG@tucnak>
     [not found] ` <68578b43-939-1879-9676-2ea55249a2c5@codesourcery.com>
2023-06-13  6:28   ` [RFC] Add stdckdint.h header for C23 Jakub Jelinek
2023-06-13 15:10     ` Joseph Myers
2023-06-13 15:20       ` Jakub Jelinek
2023-06-13 15:45         ` Joseph Myers
2023-06-14  2:54     ` Paul Eggert
2023-06-14  6:49       ` Jakub Jelinek
2023-06-14 11:46       ` Florian Weimer
2023-06-14 14:52       ` Joseph Myers
2023-06-14 15:50         ` Zack Weinberg

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).