On 8/10/21 7:48 AM, Segher Boessenkool wrote:
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 :-)
The whole point is that this data type is only used for interfaces, as
shown in the example code. Nobody wants to define const void as
anything. The const serves only as a contract that the pointed-to
object, no matter what it is cast to, will not be modified.
I think you're over-thinking this. :-)
Bill
Segher