Frederick said:
Noah Roberts posted:
Forgive me, the behaviour is "unspecified" rather than "undefined".
These are very different.
Page 88 of the current Standard:
When quoting the standard it is better to use section numbers instead
of page numbers. It is page 100 of the one I'm looking at right now.
The section you are quoting is 5.9
| If two pointers p and q of the same type point to different objects
| that are not members of the same object or elements of the same
| array or to different functions, or if only one of them is null,
| the results of p<q, p>q, p<=q, and p>=q are unspecified.
It looks like the following program may print either "true" or "false"
regardless of whether the numerical address of "a" is greater than the
numerical address of "b":
#include <iostream>
#define TF(expr) ( (expr) ? "true" : "false" )
int main()
{
int a,b;
std::cout << TF(&b > &a);
std::cout << TF( (long unsigned)&b > (long unsigned)&a );
}
It's possible that this can print two different answers, but the behaviour
is nonetheless well-defined.
I don't think you are interpreting that paragraph correctly. Placing
your quote into context with the section it is found in you have things
such as the paragraph before the one you quote:
"If two pointers p and q of the same type point to the same object or
function, or both point one past the end of the same array, or are both
null, then p<=q and p>=q both yield true and p<q and p>q both yield
false."
And the one following:
"If two pointers point to non-static data members of the same object,
or to subobjects or array elements of such members, recursively, the
pointer to the later declared member compares greater provided the two
members arenot separated by an access-specifier label (11.1) and
provided their class is not a union."
Both of the two exceptions also have paragraphs dictating exactly how
the comparison will return. Unspecified in the former case, equal in
the later.
With this context in mind "specified" means exactly which value will be
returned by the operation and gives us some pretty clear rules about
the layout of classes and arrays. Because the locations of a and b are
not defined, in our case, the comparison of their address cannot be
specified as has been clearly done with other cases. "Unspecified" in
this case simply means that there is no way of knowing before hand what
the return of that operation will be as there are no rules governing
the relative locations of a and b; it doesn't mean it won't be a valid
comparison which is what your interpretation is.
Your interpretation of "unspecified" leans closer to "undefined"
meaning there is nothing governing what the result will be...that isn't
the case here. We can still assume the camparison is a valid one and
will result in true/false depending on the relative location in memory
of these two objects. "Unspecified" does not indicate otherwise, it
just means the implementation is free to put these objects anywhere it
wants in memory, which is different to such cases when the result is
specified.