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