Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240301211732.GB4163@brightrain.aerifal.cx>
Date: Fri, 1 Mar 2024 16:17:32 -0500
From: Rich Felker <dalias@...c.org>
To: Jₑₙₛ Gustedt <jens.gustedt@...ia.fr>
Cc: musl@...ts.openwall.com
Subject: Re: adding C23 support

On Fri, Mar 01, 2024 at 08:57:44PM +0100, Jₑₙₛ Gustedt wrote:
> > Some questions:
> > 
> > - Do the final stdbit.h interfaces require external functions, or is a
> >   header-only implementation acceptable? Has anything changed on these
> >   we need to be aware of?
> 
> Yes, these require all external functions, besides for the tg
> interfaces.

That's unfortunate. It's a really huge number of functions that it's
hard to imagine anyone wanting as external rather than inline.
Normally we aim to put everything in independent TUs, but I think here
that might end up overflowing the ar/link command lines or something
if we did it.

> I think I have changed things since we last discussed, because I (and
> I was joined by many on the C committee ;-) had misunderstood some of
> the interfaces, which direction the bit count went and stuff like
> that. A thorough review would be necessary and appreciated.

Ok, so this is going to be one of the slow parts...

> > - Your stdckdint.h is header-only and is basically just a wrapper for
> >   gcc/clang builtins. If this is the case, does it make sense for it
> >   to be supplied by libc at all rather than by the compiler?
> 
> For modern compilers it definitively would make sense. But it is an
> important step to make these interfaces portable, all this discussion
> on making C safer on integer overflow.
> 
> So it would probably also good to have them independently from C23
> even for old compilers that have the builtins. Then a simple check
> with `__has_include` would make them available for everybody.
> 
> I have the impression that these interfaces reach far back in history.
> A difficulty to make them testable at library-compilation time by
> tooling is that they don't depend on the compiler with which the C
> library is compiled but on the compiler that the application has in
> hand when compiling their code.
> 
> (`__has_include` is also in C23 but has been around since ages, so
> this provides cheap test for people to see if an interface is
> provided.)

Oh, it's standard now? That's very nice!

> > - I don't understand the __STDC_VERSION_*_H__ macros. Are these a
> >   requirement of C23,
> 
> yes
> 
> >  and if so, what are the rules for the values?
> 
> the final values are all `202311L`. They are meant to dissociate from
> the C version that the compiler provides and provide means to test for
> the presence of particular parts of C23 library support.  So C
> libraries can improve step by step. For example you could upgrade the
> macro for <stdio.h> as soon as its ready, and do <math.h> much later,
> or people could even have libmath provided from somewhere else.
> 
> >   I'm not sure if it makes sense to use these as the inclusion-guards
> 
> That was your idea, really ;-)
> 
> >   if it might make sense to define them with varying values depending
> >   on feature profile; in that case, it might break optimization
> >   against multiple-include. However we end up doing these I'd probably
> >   like to make one clean commit converting all the headers to the same
> >   approach at once, rather than mixing it with other changes.
> 
> I'd really advise against that. It is really meant to be on a per
> header base, that's why there are so many of them. In particular,
> <math.h> is really a large piece of work, that could delay us for
> months or even years.

OK, I seem to have forgotten past conversations on this, so I'll see
if I can dig something up.

> > - I think all the const-safe macro things admit a solution that
> >   doesn't repeat the call or require const-casting hacks, and that may
> >   not even need _Generic, just using a cast on the return value with
> >   typeof, ala:
> > 
> >   #define memchr(p,c,n) ((typeof(1?(p):(void *)1))memchr(p,c,n))
> > 
> >   It looks like char/void issues make the str* ones a little bit
> >   tricker but I think they ultimately admit the same approach.
> 
> Yes, maybe, I'll look into these, too.
> 
> (And so you think that `typeof` is more portable than generic? Or is
> it just that this is simpler?)

It's that it follows a DRY principle, and avoids the extra creative
machinery you were trying to do to get warnings/errors to appear in
the right places due to how multiple clauses of _Generic are handled.

I think the char version might still need _Generic, but it would be a
_Generic outside/in-front-of the call (as a subexpression of the
typeof for the cast) without anything complex inside it.

Re: "more portable", these are only used conditional on >= C23, in
which case either is available.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.