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

Reply via email to