Keith said:
That doesn't prove anything. gcc, even in conforming mode, produces
warnings rather than error messages for things that are constraint
violations as far as the standard is concerned.
The standard requires a diagnostic for any syntax error or constraint
violation. Either a warning (which allows the compilation to succeed)
or an error message (which does) qualifies as a diagnostic. And, of
course, it's allowed to produce any additional diagnostics it likes.
We can't tell from the above output whether the warning is a required
diagnostic or not.
The assertion made by Emmanuel was that all compilers that he was aware
of forbade the dereferencing of void pointers. He didn't mention any
of these compilers but gcc was obviously one of them. I produced a
program that was successfully compiled on several versions of gcc in
strictly-conforming mode, none of why "forbade" my doing so. When
pressed, Emmanuel could not back up his claims (see his response).
Additionally, the other compilers I tried in strictly-conforming mode
produced no messages at all.
If a compiler in conforming mode doesn't produce a diagnostic for the
above program, we can conclude either that the code has no syntax
errors or constraint violations, or that the compiler is buggy.
C99 6.5.3.2p2 says
The operand of the unary * operator shall have pointer type.
6.5.3.2p4 says
The unary * operator denotes indirection. If the operand points to
a function, the result is a function designator; if it points to
an object, the result is an lvalue designating the object. If the
operand has type "pointer to type", the result has type "type". If
an invalid value has been assigned to the pointer, the behavior of
the unary * operator is undefined.
It seems ambiguous to me.
Well, lets break it down then:
'The operand of the unary * operator shall have pointer type.'
I think we agree that this is clear.
'The unary * operator denotes indirection. If the operand points to a
function, the result is a function designator; if it points to an
object, the result is an lvalue designating the object.'
The operand does not point to a function and it does not point to an
object (if you disagree with this, see the discussion on comp.std.c but
bear with me) so this part does not apply to void pointers.
'If the operand has type "pointer to type", the result has type "type"'
For a "pointer to void" the result has type "void". I think this is as
clear as you can expect.
'If an invalid value has been assigned to the pointer, the behavior of
the unary * operator is undefined.'
Thus, dereferencing an uninitialized void pointer or a void pointer
initialized to NULL would invoke undefined behavior.
The only thing I think is capable of being misunderstood here is
whether a void pointer "points to an object". If you think the
Standard says it does, then the following sentence would be an obvious
contradiction, a void type cannot be an lvalue.
Robert Gamble