wrote:
It says specifically "If the lvalue expression is obtained by applying the
unary * operator to a pointer". That's not the case for "1 ? *ptr : *ptr".
Consider an expression such as `base[0]`.
Do you think the authors of the Holy Standard meant that there should be
no nullpointer checking for `base[0]`, which is a syntactical form not
involving a manifest outermost application of *?
If you think no checking for base[0], then what do you think the PURPOSE
of the checking is then, that so much effort is expended on it?
But if you think yes of course also checking for base[0], then how is
that case covered by your interpretation of the standard as referring to
visual form?
Now that's your dilemma, that your interpretation does not make sense
technically, but only as support for an original position. It either
yields meaningless behavior (checking for *p, not for p[0]). Or else it
is completely arbitrary (p[0] arbitrarily included in category of unary
* applications, (1:*p:*p) not included).
The lvalue that's used is the lvalue that the conditional operator produces.
But for "*ptr", the lvalue is directly produced by applying unary * to a
pointer.
So, you mean that p[0] needs not be checked?
Then what do you think the purpose is of this checking?
E.g. how reliable is it as a diagnostic tool?
That difference is why the following difference exists in C++0x (and major
C++03 compilers):
struct A {
static int const value = 0;
};
int q2 = +A::value;
int q2 = +(1 ? A::value : A::value);
For the second case, you need a definition of A::value, which the code
doesn't provide. For the first case, you don't, because "the lvalue-to-
rvalue conversion (4.1) is immediately applied". In the second case it is
not applied immediately to the lvalue obtained by evaluating "A::value".
This is a defect in or shortcoming of the standard's notion of "used",
defined by the ODR rule. In C++98 it was horrible, not useful for
anything; that is, the practice did not rely on the standard in this
respect, the standard was impotent, and e.g. the Boost guys got
themselves a big surprise. In C++0x it has been cleaned up but is
perhaps still too defective for use in practice; we'll see.
In the above's q2 example A::value is an object that in the C++0x
standard's words "satisfies the requirements for appearing in a constant
expression" and where "the lvalue-to-rvalue conversion is immediately
applied". Which means that it's NOT "odr-used". Which means that you do
not need a formal definition (which, readers beware, is not the in-class
declaration providing a value, which formally here is just a
declaration!, but is a separate declaration outside the class body).
Since the point may not be very visible, lemme repeat: you do not
formally need a definition in C++0x, and in C++98 you only needed it due
to a defect, so in C++98 discussing the formal was meaningless.
Anyway, it's a fallacious diversion.
An example that the standard is ungood in some other way, as you provide
above, does not mean that it is also ungood wrt. `typeid`.
Cheers & hth.,
- Alf