Boon wrote: [...]
AFAICT, (sizeof *(one ? 0 : (char *)0)) is always 1
(Because the above ?: expression has type char *)
Yes.
er, why is it always of type char* why does the unadorned
0 have thype char*. This is a genuine confusion I'm having!
The unadorned 0 doesn't have type char*; it has type int, as it always
does. It also happens to be a null pointer constant. (char*)0 has
type char*, and is not a null pointer constant. The standard's
description for the conditional operator says "if one operand is a
null pointer constant, the result has the type of the other operand",
so the expression (one ? 0 : (char *)0) has type char*.
ok, but what is the type of a null pointer constant?
It depends on the null pointer constant. The fact that an expression
is a null pointer constant doesn't affect its type. For example, 0,
0ULL, and (void*)0 are all null pointer constants; their types are
int, unsigned long long, and void*, respectively. (A null pointer
constant may be converted to some pointer type, but the expression
itself has whatever type it would have if it weren't a null pointer
constant.)
but what type of pointer?
In this case, char*. If the second and third operands are a null
pointer constant and an expression of pointer type (in either order),
then the type of the null pointer constant is irrelevant; the result
of the conditional operator has the type of the operand that isn't a
null pointer constant.
It almost looks like there might be an ambiguity if both the second
and third operands are null pointer constants, but I think all
possible cases are unambiguous. If both are integer constant
expressions (with the value zero), then the rule for when both
operands have arithmetic type applies, since neither operand is a
pointer. If one is an integer constant expression and the other is of
type void*, then the rule for when one is a pointer (the void*
operand) and the other is a null pointer constant (the integer
constant expression) applies, and the result is of type void* (and is
a null pointer, whichever way the condition goes). If both are of
type void*, then the result is of type void* (and is a null pointer,
whichever way the condition goes).
The type of a null pointer constant is always either an integer type
or void*.
[snip]