On Tue, Aug 10, 2021 at 07:17:54AM -0500, Bill Schmidt wrote:
> On 8/9/21 6:44 PM, Segher Boessenkool wrote:
> >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.
> >
> I'm not sure how you get to this, but all we're doing here is standard C.

Arithmetic on void* is the GCC extension.  sizeof(void) is 1 as GCC
extension, instead of being undefined.  Pointer arithmetic is only
defined for arrays of the type being pointed to, and you cannot have an
array of void.  You can do this as GCC extension though, it behaves as
if it was a char* instead.

> x.c:
> 
> char
> foo (const void *x)
> {
>   const char *y = (const char *) x;
>   return *y;
> }

And this behaves exactly the same if you do s/const void/void/ .  The
const qualifier is meaningless on things of type void, since you cannot
have an lvalue of that type anyway.  And all type qualifiers can be cast
away (or cast into existence).

> y.c:
> 
> void
> foo (const void *x, char c)
> {
>   const char *y = (const char *) x;
>   *y = c;
> }
> 
> wschmidt@rain6p1:~/src$ gcc -c x.c
> wschmidt@rain6p1:~/src$ gcc -c y.c
> y.c: In function 'foo':
> y.c:5:6: error: assignment of read-only location '*y'
>    *y = c;
>       ^

Yes, *y is an lvalue.  *x is not: *x is an error.


It *is* allowed to have a "const void", but it means exactly the same as
just "void" (you cannot assign to either!)  And, they are compatible
types, too, (they are the *same* type in fact!), so if you ever would
treat them differently it would be mightily confusing :-)


Segher

Reply via email to