What is "what"? The result is defined to have a type. The result
_is_ a result. It _has_ a type.
It doesn't point to an object. But it does point to an object type.
Agreed for '(char *)0'. Not so for '(void *)0'. I'm with you here,
though.
There are three ways we can consider this text. Both yield identical
conclusions.
METHOD #1:
"Has been assigned to" is clumsy wording, but it obviously includes any
possible case in which a pointer *has* an invalid value.
Agreed on clumsy wording, if and only if it's not _intentional_. That
remains to be proven or at the very least, demonstrated. What makes
this obvious to you?
A null pointer
is by definition invalid,
Invalid _what_? A null pointer is a valid value for assignment, is it
not? If you are specifically referring to the context of the
evaluation of the expression '*(char *)0', your claim just above
_requires_ us to accept your previous claim before that; namely, that
"has been assigned" is clumsy and that it includes the case where the
pointer _has_ an invalid value. Furthermore, the non-normative
footnote is the only clue we have as to the possibility of a null
pointer being such an invalid value.
because it doesn't point to an object. The
behavior is undefined.
You have invented the requirement for the pointer operand to "point to
an object". Consider a function pointer. You have invented
supposedly undefined behaviour. In this Method #1, you have not
convinced me, I'm sorry to say. I was hopeful. It might even be of
no consequence to you whether I've been convinced or not. That's
fine.
Where I might say "invented" below, I additionally mean, "or have not
cited a reference which supports."
METHOD #2:
Consider more closely this sentence:
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.
This offers the sum total of definitions of the behavior of the unary-*
operator.
Considered. You have just invented the offering that this sentence is
the sum total of definitions of the behaviour for the operator. If
that were so, we could discard the statement regarding type. In fact,
why is that statement in there at all? If the sentence you reference
just above is the "sum total" you describe, why would there be any
reason to add a further definition for the result's type? I propose
that the evaluation result can thus have a type and not be one of an
lvalue, a function designator. I would be much more convinced of the
validity of this Method #2 if the referenced text either explained
that one of these possibilities is required, or some other portion of
the draft explained that sentences like these have such a requirement
implicitly. This Method #2 does not address the "has been assigned to
the pointer", which would make it even more convincing to me.
Since the operand does not point to a function or an object, its
behavior is not defined by this sentence. The behavior is undefined.
This claim requires acceptance of the disputed claim above whereby the
sentence is the "sum total" of definitions for the result of
evaluation. Acceptance of that claim means we can discard the
possibility of invalid values being assigned to the pointer. Thus,
the "has been assigned to" sentence could be discarded. So why is it
in there at all, along with the definition of the type?
METHOD #3:
Let's imagine that the "type" argument is meaningful, and that since the
operand has a *type* of a pointer-to-object, the result is "an lvalue
designating the object".
It does _not_ have type pointer-to-object. The expression '(char *)0'
has type pointer-to-char. 'char' can certainly _be_ the type _for_ an
object. '(char *)0' certainly _isn't_ a pointer-to-object, as it is a
null pointer, "guaranteed to compare unequal to a pointer to any
object or function" according to 6.3.2.3, point 3. The result is thus
_not_ "an lvalue designating the object."
Then let's see 6.3.2.1, paragraph 1:
An lvalue is an expression with an object type or an
incomplete type other than void; if an lvalue does not
designate an object when it is evaluated, the behavior is
undefined.
It does not designate an object, we evaluate it, therefore the behavior is
undefined.
This claim requires acceptance of the disputed claim above that the
result must be an lvalue because the type of the operand is pointer-to-
char. If the result is not an lvalue, evaluation of the result is not
evaluation of an lvalue and the above reference does not apply.
What it comes down to is: Dereferencing null pointers yields undefined
behavior. We know this, the standard is adequately clear on it,
We _don't_ know this. Some of us, possibly the majority, _believe_
it. According to some of your arguments, the standard is adequately
clear on it. Why then does Method #1 detail "clumsy wording"? That
would appear to make it inadequately clear. Do we discard Method #1
or do you instead mean, "so far, everyone I've ever known to interpret
null pointer indirection shares the interpretation I have."
and running
around ignoring parts of it at random
Which parts have been ignored? Your 6.3.2.1, point 1 has been
considered and responded to. If I have ignored a cited reference in
another responder's response, then I would be glad of it being brought
to my attention, so I can settle this matter to rest once and for all,
and forget about all of the opinions, inventions, and what appear to
be some plain-and-simple "No, you can't [but I cannot seem to put my
finger on exactly why]" responses that I am interpreting.
I'm not running around. I'm not dead-set in thinking that there
_is_no_ undefined behaviour. I found that there _is_ undefined
behaviour for evaluation of the expression '(void)*(cast *)0;' Nobody
has shown it (UB for '*(char *)0' yet to a satisfactorily reasonable
degree without invoking "I don't believe the intended meaning is
congruent with your interpretation; the wording could be improved" I
have provided a few arguments regarding _no_need_ for the evaluated
result to imply undefined behaviour; only the remote possibility that
implementations with a desire to conform might need to be aware of or
revisit a couple of scenarios and treat the behaviour as defined
rather than undefined. I was hopeful that "obvious" meant that there
was a simple sequence of reasoning to follow based on the text of the
draft or of a standard of C. This hope remains, with the kind
intentions and assistance of responders such as yourself.
or adding extra significance to
"has been assigned" does not change it.
This is backwards. I am _not_deducting_ significance from "has been
assigned." You and other kind responders have been deducting. My
arguments treat the significance literally, do they not?
The indirection operator does not
have any defined behavior when applied to something which is not a pointer
to an object.
Except that pointers to functions are defined, as well as with the
defined behaviour of having a result with a type. Thus this claim is
false. The claim does, however, certainly re-emphasize the
commonality of this argument throughout this thread.
The behavior is undefined. It is up to you whether you prefer
to think of this as being undefined because the lvalue does not generate
an object, or because * is not defined in its behavior when not given a
pointer to an object-or-function; either way, it's undefined.
You require one of the previous claims to be true here. You suggest
that the definition of the result's type makes for an incomplete
definition for the result. I shall continue to choose "looks as
though it's defined," instead. This might be of no consequence to
you, but I do appreciate your attempts to provide evidence.
We could doubtless improve the text with something like "if the pointer
does not point to an object or function, the behavior is undefined", but
that the text could be improved does not mean that there is any ambiguity
here.
You have brought to light two points of ambiguity:
1. The semantic point including "has been assigned to" may only be
intended to mean "if the value of the pointer is an invalid value."
In which case, there still is no normative definition for what
constitutes an invalid value, though we have a hint from the footnote.
2. The semantic point's sentence regarding the result's type should
not be specified independently from the other two definitions of
_possible_ properties of the result, given certain circumstances.
In some cases, you can assert confidently that the wording is
poor but that the meaning is clear, and this is one of those cases.
At this time, I cannot. You and some others have.
Thank you so much!