user3528438 user3528438 - 1 month ago 9
C Question

How to understand the conversion rule when a "pointer to an object type" compares for eqality with a "pointer to a void"?

n1570 6.5.9.5 (Equality operators) says:


5 ......If one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void, the former is converted to the type of the latter.


If "former" is "latter" are "pointer to object type" and "pointer to a void", then it means, after the conversion, the compare happens on two
void*
s, which according to 6.5.9.2, is undefined:


2.One of the following shall hold:

both operands have arithmetic type;

both operands are pointers to qualified or unqualified versions of compatible types;

one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void; or

one operand is a pointer and the other is a null pointer constant.


Is this an language defect in N1570?

Answer

If "former" is "latter" are "pointer to object type" and "pointer to a void", then it means, after the conversion, the compare happens on two void*s,

Yes, that's certainly how I read it.

which according to 6.5.9.2, is undefined:

No. You quote section 6.5.9.2 of the standard, apparently in the belief that the case you are asking about is not covered by that section's enumerated list of alternatives, but you are mistaken. This alternative covers the case:

one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void;

It is important here to understand that a pointer to void is a pointer to an object type, for

The void type comprises an empty set of values; it is an incomplete object type that cannot be completed.

(6.2.5/19; emphasis added)

6.5.9.2 should not be interpreted to suggest that void is not an object type; rather it says that void * is comparable to all object pointer types, including, of course, itself.

As @SouravGhosh observed first, this alternative also covers the case in question:

both operands are pointers to qualified or unqualified versions of compatible types

for every type is compatible with itself (6.2.7/1).

Comments