Defect Report #172
 
Submission Date: 16 Oct 95
Submittor: BSI
Source: Clive D.W. Feather
Question
Submitted to BSI by Clive D.W. Feather  clive@sco.com .
In this Defect Report, identifiers lexically identical to those 
declared in standard headers refer to the identifiers declared in  those
standard headers, whether or not the header is explicitly mentioned.
This Defect Report has been prepared with considerable help from 
Mark Brader, Jutta Degener, Ronald Guilmette, and a person whose
employment  conditions require anonymity. However, except where stated,
opinions  expressed or implied should not be assumed to be those of any
person  other than myself.
 Defect Report UK 020: Relational and equality operators
 The descriptions of these operators with pointer operands contain 
several defects.
Part 1
 Consider the following code:
char *s = "a string";
 if (s  = NULL)
 	/* ... */
 Subclause 6.3.8, Semantics reads in part:
 If the objects pointed to are not members of the same aggregate 
or union object, the result is undefined
 This implies that the comparison causes undefined behavior.
 Subclause 6.2.2.1 reads in part:
 Such a pointer, called a null pointer, is guaranteed to compare 
unequal to a pointer to any object or function.
 This implies that the comparison is guaranteed to yield false.
 This is a direct contradiction.
Part 2
 Subclause 6.3.9, Semantics reads in part:
 Where the operands have types and values suitable for the
relational  operators, the semantics detailed in subclause 6.3.8 apply.
 This can reasonably be read as meaning that, whenever the
constraints  of subclause 6.3.8 apply, its definitions should be used,
even if  that would result in undefined behavior. (The phrase and
values  can reasonably be read as requiring only that the pointers
both be  to objects; it does not necessarily mean that the result of the
comparison  must be defined.)
 It further reads:
 If two pointers to object or incomplete types are both null 
pointers, they compare equal. If two pointers to object or incomplete 
types compare equal, they both are null pointers, or both point to  the
same object, or both point one past the last element of the same  array
object.
 This says nothing about the comparison of any other pointers. Now,
 subclause 3.16 reads in part:
 Undefined behavior is otherwise indicated ... by the omission  of
any explicit definition of behavior.
 Thus, in:
int a, b;
&a == &b
 the comparison causes undefined behavior!
Part 3
 The above citation does not allow for the case where one pointer
is  to an object, and the other is one past the last element of an array
 object. If an implementation places two independent objects in adjacent
 memory locations, a pointer to one would equal a pointer to just past 
the other on many common implementations.
 If these pointers are not to be viewed as identical, then the
wording  is defective.
Suggested Technical Corrigendum
 In subclause 6.2.2.1, replace the cited text by:
 Such a pointer is called a null pointer.
 In subclause 6.3.9, replace the first paragraph of the semantics
by:
 The operators == (equal to) and !=
(not equal to)  shall yield 1 if the specified relation is true and 0 if
it is false.  If the operands have types suitable for those of a
relational operator  and values that would not cause undefined behavior
if used with a  relational operator, then the result of the comparison,
either greater  than or less than (both implying not equal to) or equal
to, is the  same as with a relational operator.
 Insert at the start of the second paragraph:
 Otherwise the operands are pointers, and they shall compare 
either equal or not equal.
 If part 3 is viewed as an issue, then in the same paragraph
change:
 or both point one past the last element of the same array object.
 to:
 both point one past the last element of the same array object,  or
one points one past the last element of some array object and the  other
points to the first element of a different array object.
 Response
 This is a work in progress item.
 Summary of Part 1:
 The standard does not currently state what happens with relational
 operators when you compare the address of an object with a null
pointer.
 We know from the citation from subclause 6.2.2.3 that a null
pointer  is guaranteed to yield false when compared with a pointer to an
object.
 It is explicitly undefined behaviour to use relational operators
on  two pointer that are not members of the same aggregate or union
object.  However it is unstated whether a null pointer compares greater
or  less than the address of an object and hence is implicitly undefined
 behaviour.
 Is this the desired behaviour?
 Note: the current C++ clause has the following wording:
 If two pointers of the same type point to different objects  or
functions, or only one of them is null, they compare unequal.
 This wording gives the possibility for C and C++ to give different
 results.
 Summary of Part 2:
 Discussion from Nashua is as follows:
 The intent is that pointers to distinct object will compare
unequal,  The C Standard will be fixed in a future revision. 
Previous Defect Report
< - > 
Next Defect Report