On Mon, Aug 09, 2021 at 02:18:48PM -0500, Bill Schmidt wrote:
> >>"const void" is meaningless, and maybe even invalid C. I think the code
> >>is wrong, not (just) the documentation! This wants to be
> >> void *const
> >>but it is
> >> const void *
> >>as far as I can see?
> >>
> >>As I said, this isn't new code, but it seems very wrong!
> >
> I had to go back and remember where this fits in. tl;dr: This is fine.
> :-) More details...
>
> "const void *" is used as part of the overloading machinery. It serves
> to reduce the number of built-in functions that we need to register with
> the front end. Consider the built-in function that accesses the "lvebx"
> instruction. In rs6000-builtin-new.def, we define it this way:
>
> pure vsc __builtin_altivec_lvebx (signed long, const void *);
> LVEBX altivec_lvebx {ldvec}
>
> Note that this is a "pure" function (no side effects), and we
> contractually guarantee (through "const <type> *") that we will not
> modify the data pointed to by the second argument.
"void" can never be an lvalue (it is an incomplete type), so "const" on
it is meaningless (it is not invalid C though afaics).
> However, we don't have that freedom with pointer types. This is why the
> built-in function is defined with a void * argument. Both "const signed
> char *" and "const unsigned char *" can be legitimately cast to a "const
> void *".
Why? "void" is not an object type at all.
This is not a documented GCC extension either, and it might even
conflict with the existing void * extension (allowing arithmetic on it,
by defining sizeof(void)). In either case it is not currently defined.
You can assign a pointer to qualified to a pointer to unqualified (and
the other way around) just fine, fwiw. You can cast (explicitly or
implicitly) exactly the same things to void * as you can to const void *.
> This isn't strictly necessary, but without such a trick, we would have
> to have two different __builtin_altivec_lvebx functions (with different
> names) to handle the different pointer types. Defining multiple
> functions for each such situation is wasteful when defining functions
> and when looking them up, and a naming scheme would be needed for
> dealing with this.
So apparently the GCC overload semantics do not have much to do with how
C works otherwise? This sounds not ideal :-/
> This is the way the builtin structure has been working since the "dawn
> of time," and I'm not proposing changes to that. I'm hopeful with the
> new system that it is a little clearer what is going on, though, since
> you can easily see the const void * arguments in the definitions.
Yeah, me too. But it all sounds just wrong.
Segher