473,388 Members | 1,526 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,388 software developers and data experts.

pointer equality

In K&R "The C++ programming language (2nd ANSI C edition), the reference
manual states (paragraphs 7.9 and 7.10) that pointer comparison is
undefined for pointers that do not point to the same object.

So if we have

const char * foo = "foo" , * bar = "bar" ;
int foobar = ( foo == bar ) ;

would it mean that foobar is undefined?

I knew that relational operators (<,<=,>=,>) cannot be used on pointers
to different objects, but how about equality operators ==,!= ?

Regards,
Ike

mail to ike at iae dot nl
Nov 14 '05 #1
40 5637
On Tue, 06 Apr 2004 21:25:13 GMT, Ike Naar <no****@nospam.invalid> wrote:
In K&R "The C++ programming language (2nd ANSI C edition), the reference
manual states (paragraphs 7.9 and 7.10) that pointer comparison is
undefined for pointers that do not point to the same object.

So if we have

const char * foo = "foo" , * bar = "bar" ;
int foobar = ( foo == bar ) ;

would it mean that foobar is undefined?
How are you reading that? I'm seeing:

"Pointers to objects of the same type (ignoring any qualifiers)
may be compared"
I knew that relational operators (<,<=,>=,>) cannot be used on pointers
to different objects
Why not?
int a[10];
int *p1 = &a[3];
int *p2 = &a[4];
if (p2 > p1)
...

Perfectly legal.
, but how about equality operators ==,!= ?
Of course, to test if the pointers point to the same object or not...
-leor

Regards,
Ike

mail to ike at iae dot nl


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Nov 14 '05 #2
On Tue, 06 Apr 2004 21:25:13 GMT, Ike Naar <no****@nospam.invalid> wrote:
In K&R "The C++ programming language (2nd ANSI C edition), the reference
manual states (paragraphs 7.9 and 7.10) that pointer comparison is
undefined for pointers that do not point to the same object.

So if we have

const char * foo = "foo" , * bar = "bar" ;
int foobar = ( foo == bar ) ;

would it mean that foobar is undefined?
How are you reading that? I'm seeing:

"Pointers to objects of the same type (ignoring any qualifiers)
may be compared"
I knew that relational operators (<,<=,>=,>) cannot be used on pointers
to different objects
Why not?
int a[10];
int *p1 = &a[3];
int *p2 = &a[4];
if (p2 > p1)
...

Perfectly legal.
, but how about equality operators ==,!= ?
Of course, to test if the pointers point to the same object or not...
-leor

Regards,
Ike

mail to ike at iae dot nl


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Nov 14 '05 #3
In article <Ze****************@typhoon.bart.nl>,
Ike Naar <no****@nospam.invalid> wrote:
In K&R "The C++ programming language (2nd ANSI C edition), the reference
manual states (paragraphs 7.9 and 7.10) that pointer comparison is
undefined for pointers that do not point to the same object.

So if we have

const char * foo = "foo" , * bar = "bar" ;
int foobar = ( foo == bar ) ;

would it mean that foobar is undefined? I knew that relational operators (<,<=,>=,>) cannot be used on pointers
to different objects, but how about equality operators ==,!= ?


< <= > >= cannot be legally used on pointers to different objects; ==
and != can. So either the book you mentioned is wrong, or you missed
something when you read it. You might want to re-read it and see if it
mentions "relational operators" and "equality operators". If you are
sure you don't misunderstand anything, you should probably post a bit
more literally from that book.
Nov 14 '05 #4
In article <Ze****************@typhoon.bart.nl>,
Ike Naar <no****@nospam.invalid> wrote:
In K&R "The C++ programming language (2nd ANSI C edition), the reference
manual states (paragraphs 7.9 and 7.10) that pointer comparison is
undefined for pointers that do not point to the same object.

So if we have

const char * foo = "foo" , * bar = "bar" ;
int foobar = ( foo == bar ) ;

would it mean that foobar is undefined? I knew that relational operators (<,<=,>=,>) cannot be used on pointers
to different objects, but how about equality operators ==,!= ?


< <= > >= cannot be legally used on pointers to different objects; ==
and != can. So either the book you mentioned is wrong, or you missed
something when you read it. You might want to re-read it and see if it
mentions "relational operators" and "equality operators". If you are
sure you don't misunderstand anything, you should probably post a bit
more literally from that book.
Nov 14 '05 #5
Christian Bau <ch***********@cbau.freeserve.co.uk> wrote:

: Ike Naar <no****@nospam.invalid> wrote:
:> In K&R "The C++ programming language (2nd ANSI C edition), the reference
:> manual states (paragraphs 7.9 and 7.10) that pointer comparison is
:> undefined for pointers that do not point to the same object.

: < <= > >= cannot be legally used on pointers to different objects; ==
: and != can. So either the book you mentioned is wrong, or you missed
: something when you read it. You might want to re-read it and see if it
: mentions "relational operators" and "equality operators".

Thanks for your response.

Paragraph 7.9 describes relational operators and explains how these
operators can only be used on pointers pointing to the same object.

Paragraph 7.10 describes equality operators, and describes them as
analogous to relational operators, except that equality operators can
also be used to compare a pointer to an object and the null pointer.

: If you are
: sure you don't misunderstand anything, you should probably post a bit
: more literally from that book.

I don't have the book at hand now, but I can quote the paragraphs when
I get back to work in the morning.

--
mail to ike at iae dot nl
Nov 14 '05 #6
Christian Bau <ch***********@cbau.freeserve.co.uk> wrote:

: Ike Naar <no****@nospam.invalid> wrote:
:> In K&R "The C++ programming language (2nd ANSI C edition), the reference
:> manual states (paragraphs 7.9 and 7.10) that pointer comparison is
:> undefined for pointers that do not point to the same object.

: < <= > >= cannot be legally used on pointers to different objects; ==
: and != can. So either the book you mentioned is wrong, or you missed
: something when you read it. You might want to re-read it and see if it
: mentions "relational operators" and "equality operators".

Thanks for your response.

Paragraph 7.9 describes relational operators and explains how these
operators can only be used on pointers pointing to the same object.

Paragraph 7.10 describes equality operators, and describes them as
analogous to relational operators, except that equality operators can
also be used to compare a pointer to an object and the null pointer.

: If you are
: sure you don't misunderstand anything, you should probably post a bit
: more literally from that book.

I don't have the book at hand now, but I can quote the paragraphs when
I get back to work in the morning.

--
mail to ike at iae dot nl
Nov 14 '05 #7
Leor Zolman <le**@bdsoft.com> wrote:

: On Tue, 06 Apr 2004 21:25:13 GMT, Ike Naar <no****@nospam.invalid> wrote:
:>In K&R "The C++ programming language (2nd ANSI C edition), the reference
:>manual states (paragraphs 7.9 and 7.10) that pointer comparison is
:>undefined for pointers that do not point to the same object.

: How are you reading that? I'm seeing:
: "Pointers to objects of the same type (ignoring any qualifiers)
: may be compared"

The rest of that sentence mentions that the pointers should point
to the same object, and that the comparison is otherwise undefined.

: int a[10];
: int *p1 = &a[3];
: int *p2 = &a[4];
: if (p2 > p1)
: Perfectly legal.

That's what everybody would expect, but not what K&R seem to say.
Nov 14 '05 #8
Leor Zolman <le**@bdsoft.com> wrote:

: On Tue, 06 Apr 2004 21:25:13 GMT, Ike Naar <no****@nospam.invalid> wrote:
:>In K&R "The C++ programming language (2nd ANSI C edition), the reference
:>manual states (paragraphs 7.9 and 7.10) that pointer comparison is
:>undefined for pointers that do not point to the same object.

: How are you reading that? I'm seeing:
: "Pointers to objects of the same type (ignoring any qualifiers)
: may be compared"

The rest of that sentence mentions that the pointers should point
to the same object, and that the comparison is otherwise undefined.

: int a[10];
: int *p1 = &a[3];
: int *p2 = &a[4];
: if (p2 > p1)
: Perfectly legal.

That's what everybody would expect, but not what K&R seem to say.
Nov 14 '05 #9
Ike Naar wrote:
Leor Zolman <le**@bdsoft.com> wrote:

: On Tue, 06 Apr 2004 21:25:13 GMT, Ike Naar <no****@nospam.invalid> wrote:
:>In K&R "The C++ programming language (2nd ANSI C edition), the reference
:>manual states (paragraphs 7.9 and 7.10) that pointer comparison is
:>undefined for pointers that do not point to the same object.

: How are you reading that? I'm seeing:
: "Pointers to objects of the same type (ignoring any qualifiers)
: may be compared"

The rest of that sentence mentions that the pointers should point
to the same object, and that the comparison is otherwise undefined.

: int a[10];
: int *p1 = &a[3];
: int *p2 = &a[4];
: if (p2 > p1)
: Perfectly legal.

That's what everybody would expect, but not what K&R seem to say.


K&R, in A7.9, says:

"Pointer comparison is defined only for parts of the same object:
[...] if the pointers refer to members of an array, the comparison
is equivalent to comparison of the corresponding subscripts."

which covers Leor's example above. The undefined case is when the
pointers are to entirely distinct objects:

int a, b;
&a == &b; /* okay */
&a > &b; /* undefined */

It's the behaviour that's undefined, not just the result, so the
comparison could cause your program to crash (in theory, at least).

Jeremy.
Nov 14 '05 #10
Ike Naar wrote:
Leor Zolman <le**@bdsoft.com> wrote:

: On Tue, 06 Apr 2004 21:25:13 GMT, Ike Naar <no****@nospam.invalid> wrote:
:>In K&R "The C++ programming language (2nd ANSI C edition), the reference
:>manual states (paragraphs 7.9 and 7.10) that pointer comparison is
:>undefined for pointers that do not point to the same object.

: How are you reading that? I'm seeing:
: "Pointers to objects of the same type (ignoring any qualifiers)
: may be compared"

The rest of that sentence mentions that the pointers should point
to the same object, and that the comparison is otherwise undefined.

: int a[10];
: int *p1 = &a[3];
: int *p2 = &a[4];
: if (p2 > p1)
: Perfectly legal.

That's what everybody would expect, but not what K&R seem to say.


K&R, in A7.9, says:

"Pointer comparison is defined only for parts of the same object:
[...] if the pointers refer to members of an array, the comparison
is equivalent to comparison of the corresponding subscripts."

which covers Leor's example above. The undefined case is when the
pointers are to entirely distinct objects:

int a, b;
&a == &b; /* okay */
&a > &b; /* undefined */

It's the behaviour that's undefined, not just the result, so the
comparison could cause your program to crash (in theory, at least).

Jeremy.
Nov 14 '05 #11
Leor Zolman <le**@bdsoft.com> writes:
On Tue, 06 Apr 2004 21:25:13 GMT, Ike Naar <no****@nospam.invalid> wrote:
I knew that relational operators (<,<=,>=,>) cannot be used on pointers
to different objects


Why not?
int a[10];
int *p1 = &a[3];
int *p2 = &a[4];
if (p2 > p1)
...

Perfectly legal.


Both pointers point to "sub-objects" contained in the same aggregate
object `a'. This is probably what the OP meant: there must be a single
object into which both pointers point.

For example, this code causes UB:

int i, j, p1 = &i, p2 = &j;
p2 > p1;

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #12
Leor Zolman <le**@bdsoft.com> writes:
On Tue, 06 Apr 2004 21:25:13 GMT, Ike Naar <no****@nospam.invalid> wrote:
I knew that relational operators (<,<=,>=,>) cannot be used on pointers
to different objects


Why not?
int a[10];
int *p1 = &a[3];
int *p2 = &a[4];
if (p2 > p1)
...

Perfectly legal.


Both pointers point to "sub-objects" contained in the same aggregate
object `a'. This is probably what the OP meant: there must be a single
object into which both pointers point.

For example, this code causes UB:

int i, j, p1 = &i, p2 = &j;
p2 > p1;

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #13
Jeremy Yallop <je****@jdyallop.freeserve.co.uk> wrote:
: K&R, in A7.9, says:
: "Pointer comparison is defined only for parts of the same object:
: [...] if the pointers refer to members of an array, the comparison
: is equivalent to comparison of the corresponding subscripts."
: [...]. The undefined case is when the
: pointers are to entirely distinct objects:
: int a, b;
: &a == &b; /* okay */

How could this be OK, if &a and &b are pointing to distinct objects?

: &a > &b; /* undefined */

: It's the behaviour that's undefined, not just the result, so the
: comparison could cause your program to crash (in theory, at least).

: Jeremy.

--
mail to ike at iae dot nl
Nov 14 '05 #14
Jeremy Yallop <je****@jdyallop.freeserve.co.uk> wrote:
: K&R, in A7.9, says:
: "Pointer comparison is defined only for parts of the same object:
: [...] if the pointers refer to members of an array, the comparison
: is equivalent to comparison of the corresponding subscripts."
: [...]. The undefined case is when the
: pointers are to entirely distinct objects:
: int a, b;
: &a == &b; /* okay */

How could this be OK, if &a and &b are pointing to distinct objects?

: &a > &b; /* undefined */

: It's the behaviour that's undefined, not just the result, so the
: comparison could cause your program to crash (in theory, at least).

: Jeremy.

--
mail to ike at iae dot nl
Nov 14 '05 #15
Ike Naar wrote:

Jeremy Yallop <je****@jdyallop.freeserve.co.uk> wrote:
: K&R, in A7.9, says:
: "Pointer comparison is defined only for parts of the same object:
: [...] if the pointers refer to members of an array, the comparison
: is equivalent to comparison of the corresponding subscripts."
: [...]. The undefined case is when the
: pointers are to entirely distinct objects:
: int a, b;
: &a == &b; /* okay */

How could this be OK, if &a and &b are pointing to distinct objects?


If &a and &b are pointing to distinct objects, then the value of
(&a == &b) is zero, and that's OK.

If &a and &b are pointing to distinct objects, then the value of
(&a > &b) is undefined, and that's bad.

--
pete
Nov 14 '05 #16
Ike Naar wrote:

Jeremy Yallop <je****@jdyallop.freeserve.co.uk> wrote:
: K&R, in A7.9, says:
: "Pointer comparison is defined only for parts of the same object:
: [...] if the pointers refer to members of an array, the comparison
: is equivalent to comparison of the corresponding subscripts."
: [...]. The undefined case is when the
: pointers are to entirely distinct objects:
: int a, b;
: &a == &b; /* okay */

How could this be OK, if &a and &b are pointing to distinct objects?


If &a and &b are pointing to distinct objects, then the value of
(&a == &b) is zero, and that's OK.

If &a and &b are pointing to distinct objects, then the value of
(&a > &b) is undefined, and that's bad.

--
pete
Nov 14 '05 #17

"Ike Naar" <no****@nospam.invalid> a écrit dans le message de
news:Uq****************@typhoon.bart.nl...

Hi,
Jeremy Yallop <je****@jdyallop.freeserve.co.uk> wrote:
: K&R, in A7.9, says:
: "Pointer comparison is defined only for parts of the same object:
: [...] if the pointers refer to members of an array, the comparison
: is equivalent to comparison of the corresponding subscripts."
: [...]. The undefined case is when the
: pointers are to entirely distinct objects:
: int a, b;
: &a == &b; /* okay */

How could this be OK, if &a and &b are pointing to distinct objects?


It's OK in the sense it's not a UB. &a == &b evaluates to false here.
Equality operators are much more reliable than relational operators in
relation to UB and don't lead specially to an UB if they are applied on
distinct objects (therefore, it often evaluates to false).
A case I know for witch an UB can occur for equality operators is when the
pointers you're going to compare (with equality ops) are invalid, like
accessing outside the bounds of arrays.

exple of (possible) UB :
....
int tab[10];
....
int *p = &tab[21];
int *q = &tab[32];
....
if (p != q) ...
{
}

Regis
Nov 14 '05 #18

"Ike Naar" <no****@nospam.invalid> a écrit dans le message de
news:Uq****************@typhoon.bart.nl...

Hi,
Jeremy Yallop <je****@jdyallop.freeserve.co.uk> wrote:
: K&R, in A7.9, says:
: "Pointer comparison is defined only for parts of the same object:
: [...] if the pointers refer to members of an array, the comparison
: is equivalent to comparison of the corresponding subscripts."
: [...]. The undefined case is when the
: pointers are to entirely distinct objects:
: int a, b;
: &a == &b; /* okay */

How could this be OK, if &a and &b are pointing to distinct objects?


It's OK in the sense it's not a UB. &a == &b evaluates to false here.
Equality operators are much more reliable than relational operators in
relation to UB and don't lead specially to an UB if they are applied on
distinct objects (therefore, it often evaluates to false).
A case I know for witch an UB can occur for equality operators is when the
pointers you're going to compare (with equality ops) are invalid, like
accessing outside the bounds of arrays.

exple of (possible) UB :
....
int tab[10];
....
int *p = &tab[21];
int *q = &tab[32];
....
if (p != q) ...
{
}

Regis
Nov 14 '05 #19
Ike Naar <no****@nospam.invalid> writes:
In K&R "The C++ programming language (2nd ANSI C edition), the reference
manual states (paragraphs 7.9 and 7.10) that pointer comparison is
undefined for pointers that do not point to the same object.

So if we have

const char * foo = "foo" , * bar = "bar" ;
int foobar = ( foo == bar ) ;

would it mean that foobar is undefined?

I knew that relational operators (<,<=,>=,>) cannot be used on pointers
to different objects, but how about equality operators ==,!= ?


I think you've found an error in K&R2. (BTW, it's "The C Programming
Language", not C++.) It's not mentioned in the errata at
<http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html> either.

Section A7.9, "Relational Operators", discusses the "<", ">", "<=",
and ">=" operators. It says, in part:

Pointers comparison is defined only for parts of the same object:
[...] Otherwise, pointer comparison is undefined.

Section A7.10, "Equality Operators", discusses the "==" and "!="
operators. It says, in part:

The equality operators follow the same rules as the relational
operators, but permit additional possibilities: a pointer may be
compared to a constant integral expression with value 0, or to a
pointer to void. See section A6.6.

(Section A6.6 doesn't address the issue of comparing pointers to
distinct objects for equality.)

The corresponding sections in the C90 and C99 standard say that
relational operators on pointers to distinct objects cause undefined
behavior (except perhaps in some obscure circumstances involving
objects that happen to be adjacent in memory), but doesn't make a
similar statement about equality operators, implying that equality
comparison of pointers to distinct objects is well-defined (and yields
the value 0).

I hesitate to suggest that the creators of the language got something
like this wrong; it can happen, but I'm hardly immune to making
mistakes myself. I encourage other readers to check my interpretation
and point out whether I've missed something or K&R have.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #20
Ike Naar <no****@nospam.invalid> writes:
In K&R "The C++ programming language (2nd ANSI C edition), the reference
manual states (paragraphs 7.9 and 7.10) that pointer comparison is
undefined for pointers that do not point to the same object.

So if we have

const char * foo = "foo" , * bar = "bar" ;
int foobar = ( foo == bar ) ;

would it mean that foobar is undefined?

I knew that relational operators (<,<=,>=,>) cannot be used on pointers
to different objects, but how about equality operators ==,!= ?


I think you've found an error in K&R2. (BTW, it's "The C Programming
Language", not C++.) It's not mentioned in the errata at
<http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html> either.

Section A7.9, "Relational Operators", discusses the "<", ">", "<=",
and ">=" operators. It says, in part:

Pointers comparison is defined only for parts of the same object:
[...] Otherwise, pointer comparison is undefined.

Section A7.10, "Equality Operators", discusses the "==" and "!="
operators. It says, in part:

The equality operators follow the same rules as the relational
operators, but permit additional possibilities: a pointer may be
compared to a constant integral expression with value 0, or to a
pointer to void. See section A6.6.

(Section A6.6 doesn't address the issue of comparing pointers to
distinct objects for equality.)

The corresponding sections in the C90 and C99 standard say that
relational operators on pointers to distinct objects cause undefined
behavior (except perhaps in some obscure circumstances involving
objects that happen to be adjacent in memory), but doesn't make a
similar statement about equality operators, implying that equality
comparison of pointers to distinct objects is well-defined (and yields
the value 0).

I hesitate to suggest that the creators of the language got something
like this wrong; it can happen, but I'm hardly immune to making
mistakes myself. I encourage other readers to check my interpretation
and point out whether I've missed something or K&R have.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #21
Keith Thompson <ks***@mib.org> wrote:

: I think you've found an error in K&R2. (BTW, it's "The C Programming
: Language", not C++.) It's not mentioned in the errata at
: <http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html> either.

I think you found an error in my article ;-)
Of course it should be "The C Programming Language".

: Section A7.9, "Relational Operators", discusses the "<", ">", "<=",
: and ">=" operators. It says, in part:
: Pointers comparison is defined only for parts of the same object:
: [...] Otherwise, pointer comparison is undefined.
: Section A7.10, "Equality Operators", discusses the "==" and "!="
: operators. It says, in part:
: The equality operators follow the same rules as the relational
: operators, but permit additional possibilities: a pointer may be
: compared to a constant integral expression with value 0, or to a
: pointer to void. See section A6.6.
: (Section A6.6 doesn't address the issue of comparing pointers to
: distinct objects for equality.)
: The corresponding sections in the C90 and C99 standard say that
: relational operators on pointers to distinct objects cause undefined
: behavior (except perhaps in some obscure circumstances involving
: objects that happen to be adjacent in memory), but doesn't make a
: similar statement about equality operators, implying that equality
: comparison of pointers to distinct objects is well-defined (and yields
: the value 0).
: I hesitate to suggest that the creators of the language got something
: like this wrong; it can happen, but I'm hardly immune to making
: mistakes myself. I encourage other readers to check my interpretation
: and point out whether I've missed something or K&R have.

I also found it hard to believe that equality comparison on valid
pointers to distinct objects would be UB, but K&R seemed to lead to
no other conclusion. That's why I asked the group.

Thank you for your response, anyway.

: --
: Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
: San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
: Schroedinger does Shakespeare: "To be *and* not to be"

--
mail to ike at iae dot nl
Nov 14 '05 #22
Keith Thompson <ks***@mib.org> wrote:

: I think you've found an error in K&R2. (BTW, it's "The C Programming
: Language", not C++.) It's not mentioned in the errata at
: <http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html> either.

I think you found an error in my article ;-)
Of course it should be "The C Programming Language".

: Section A7.9, "Relational Operators", discusses the "<", ">", "<=",
: and ">=" operators. It says, in part:
: Pointers comparison is defined only for parts of the same object:
: [...] Otherwise, pointer comparison is undefined.
: Section A7.10, "Equality Operators", discusses the "==" and "!="
: operators. It says, in part:
: The equality operators follow the same rules as the relational
: operators, but permit additional possibilities: a pointer may be
: compared to a constant integral expression with value 0, or to a
: pointer to void. See section A6.6.
: (Section A6.6 doesn't address the issue of comparing pointers to
: distinct objects for equality.)
: The corresponding sections in the C90 and C99 standard say that
: relational operators on pointers to distinct objects cause undefined
: behavior (except perhaps in some obscure circumstances involving
: objects that happen to be adjacent in memory), but doesn't make a
: similar statement about equality operators, implying that equality
: comparison of pointers to distinct objects is well-defined (and yields
: the value 0).
: I hesitate to suggest that the creators of the language got something
: like this wrong; it can happen, but I'm hardly immune to making
: mistakes myself. I encourage other readers to check my interpretation
: and point out whether I've missed something or K&R have.

I also found it hard to believe that equality comparison on valid
pointers to distinct objects would be UB, but K&R seemed to lead to
no other conclusion. That's why I asked the group.

Thank you for your response, anyway.

: --
: Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
: San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
: Schroedinger does Shakespeare: "To be *and* not to be"

--
mail to ike at iae dot nl
Nov 14 '05 #23
Ike Naar wrote:
In K&R "The C++ programming language (2nd ANSI C edition), the reference
manual states (paragraphs 7.9 and 7.10) that pointer comparison is
undefined for pointers that do not point to the same object.

So if we have

const char * foo = "foo" , * bar = "bar" ;
int foobar = ( foo == bar ) ;

would it mean that foobar is undefined?

I knew that relational operators (<,<=,>=,>)
cannot be used on pointers to different objects,
but how about equality operators ==,!= ?
cat main.c #include <stdio.h>
#include <stdlib.h>

int onStack(void* p) {
return (p > (void*)&p);
}

int main(int argc, char* argv[]) {
char c;
char* p = &c;
//char* p = (char*)malloc(sizeof(char));
if (onStack(p)) {
fprintf(stdout,"p probably points to a character "
"in automatic storage.\n");
}
else {
fprintf(stdout, "p probably points to static data "
"or free storage.\n");
}
return 0;
}
gcc -Wall -std=c99 -pedantic -o main main.c
./main

p probably points to a character in automatic storage.

I also tested with Greg Comeau's C99 compiler:

http://www.comeaucomputing.com/pcgi-bin/compiler.cgi

Your Comeau C/C++ test results are as follows:

Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C99
In strict mode, with -tused, Compile succeeded
(but remember, the Comeau online compiler does not link).

Nov 14 '05 #24
Ike Naar wrote:
In K&R "The C++ programming language (2nd ANSI C edition), the reference
manual states (paragraphs 7.9 and 7.10) that pointer comparison is
undefined for pointers that do not point to the same object.

So if we have

const char * foo = "foo" , * bar = "bar" ;
int foobar = ( foo == bar ) ;

would it mean that foobar is undefined?

I knew that relational operators (<,<=,>=,>)
cannot be used on pointers to different objects,
but how about equality operators ==,!= ?
cat main.c #include <stdio.h>
#include <stdlib.h>

int onStack(void* p) {
return (p > (void*)&p);
}

int main(int argc, char* argv[]) {
char c;
char* p = &c;
//char* p = (char*)malloc(sizeof(char));
if (onStack(p)) {
fprintf(stdout,"p probably points to a character "
"in automatic storage.\n");
}
else {
fprintf(stdout, "p probably points to static data "
"or free storage.\n");
}
return 0;
}
gcc -Wall -std=c99 -pedantic -o main main.c
./main

p probably points to a character in automatic storage.

I also tested with Greg Comeau's C99 compiler:

http://www.comeaucomputing.com/pcgi-bin/compiler.cgi

Your Comeau C/C++ test results are as follows:

Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C99
In strict mode, with -tused, Compile succeeded
(but remember, the Comeau online compiler does not link).

Nov 14 '05 #25
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> writes:
Ike Naar wrote:

[...]
I knew that relational operators (<,<=,>=,>) cannot be used on
pointers to different objects,
but how about equality operators ==,!= ?

[sample code and output snipped; see parent article if you're curious.]

The behavior of the sample program proves nothing. The question is
whether comparison of pointers to different objects invokes undefined
behavior. Since undefined behavior can do anything, including
whatever you might expect it to do, and since compilers are not
required to diagnose undefined behavior, the behavior of doesn't say
anything one way or the other.

It's clear from the C90 standard, the C99 standard, and K&R2 that
applying a relational operator to pointers to distinct objects results
in undefined behavior (K&R2 says "Otherwise, pointer comparison is
undefined."; the pre-standard K&R1 merely says it isn't portable.)
You've demonstrated that one particular instance of undefined
behavior, in one particular case, results in the program printing
"p probably points to a character in automatic storage.", which is
neither surprising nor illuminating.

(I'm assuming here that "cannot be used" is short for "cannot be used
without invoking undefined behavior". Obviously it can be used if you
don't mind undefined behavior.)

The real question is whether equality comparison of pointers to
distinct objects results in undefined behavior. The C90 and C99
standards both imply that it doesn't; K&R2 implies that it does,
unless I've misunderstood it. I presume that wasn't the intent; it
seems obvious that P1==P2 should simply yield 0 if P1 and P2 point to
distinct objects. Do you have anything useful to add to that part of
the discussion?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #26
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> writes:
Ike Naar wrote:

[...]
I knew that relational operators (<,<=,>=,>) cannot be used on
pointers to different objects,
but how about equality operators ==,!= ?

[sample code and output snipped; see parent article if you're curious.]

The behavior of the sample program proves nothing. The question is
whether comparison of pointers to different objects invokes undefined
behavior. Since undefined behavior can do anything, including
whatever you might expect it to do, and since compilers are not
required to diagnose undefined behavior, the behavior of doesn't say
anything one way or the other.

It's clear from the C90 standard, the C99 standard, and K&R2 that
applying a relational operator to pointers to distinct objects results
in undefined behavior (K&R2 says "Otherwise, pointer comparison is
undefined."; the pre-standard K&R1 merely says it isn't portable.)
You've demonstrated that one particular instance of undefined
behavior, in one particular case, results in the program printing
"p probably points to a character in automatic storage.", which is
neither surprising nor illuminating.

(I'm assuming here that "cannot be used" is short for "cannot be used
without invoking undefined behavior". Obviously it can be used if you
don't mind undefined behavior.)

The real question is whether equality comparison of pointers to
distinct objects results in undefined behavior. The C90 and C99
standards both imply that it doesn't; K&R2 implies that it does,
unless I've misunderstood it. I presume that wasn't the intent; it
seems obvious that P1==P2 should simply yield 0 if P1 and P2 point to
distinct objects. Do you have anything useful to add to that part of
the discussion?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #27

On Tue, 6 Apr 2004, Keith Thompson wrote:

Ike Naar <no****@nospam.invalid> writes:
In K&R "The C++ programming language (2nd ANSI C edition), the reference
manual states (paragraphs 7.9 and 7.10) that pointer comparison is
undefined for pointers that do not point to the same object.

So if we have

const char * foo = "foo" , * bar = "bar" ;
int foobar = ( foo == bar ) ;

would it mean that foobar is undefined?

I knew that relational operators (<,<=,>=,>) cannot be used on pointers
to different objects, but how about equality operators ==,!= ?
I think you've found an error in K&R2. (BTW, it's "The C Programming
Language", not C++.) It's not mentioned in the errata at
<http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html> either.


I don't see any error in what you've posted, except for a probable
typo.
Section A7.9, "Relational Operators", discusses the "<", ">", "<=",
and ">=" operators. It says, in part:

Pointers comparison is defined only for parts of the same object:
[...] Otherwise, pointer comparison is undefined.
Shouldn't that read "Pointer comparison is..."? Did you make any
more serious typos? (It matters. ;-)
Anyway, that excerpt states explicitly that the behavior of the
following code is well-defined:

int bar[3];
(&bar[1] >= bar+2);

because '&bar[1]' and 'bar+2' point to parts of the same object. That
is, they both point to parts of the object 'bar', which is an array[3]
of int.
Section A7.10, "Equality Operators", discusses the "==" and "!="
operators. It says, in part:

The equality operators follow the same rules as the relational
operators, but permit additional possibilities: a pointer may be
compared to a constant integral expression with value 0, or to a
pointer to void. See section A6.6.
Looks good to me.
(Section A6.6 doesn't address the issue of comparing pointers to
distinct objects for equality.)

The corresponding sections in the C90 and C99 standard say that
relational operators on pointers to distinct objects cause undefined
behavior (except perhaps in some obscure circumstances involving
objects that happen to be adjacent in memory),
Nothing obscure about that circumstance! :) IIRC, the Standard
explicitly allows

int i;
int j;
printf("%d\n", &i+1 == &j)

to print "1", if j follows i in memory, even though &i+1 and &j point
to parts of different objects (&i points to the end of the object i,
and &j points to the object j). I don't recall any similar language
about relational operators, since the case

(&i < &j)

is explicitly covered by "undefined behavior" anyway, and can print 1,
or 0, or 42, or whatever it likes.
but doesn't make a
similar statement about equality operators, implying that equality
comparison of pointers to distinct objects is well-defined (and yields
the value 0).
Except in the circumstances above. I think you're right.
I hesitate to suggest that the creators of the language got something
like this wrong; it can happen, but I'm hardly immune to making
mistakes myself. I encourage other readers to check my interpretation
and point out whether I've missed something or K&R have.


So, what do you think K&R missed? It all looks there to me.

-Arthur

Nov 14 '05 #28

On Tue, 6 Apr 2004, Keith Thompson wrote:

Ike Naar <no****@nospam.invalid> writes:
In K&R "The C++ programming language (2nd ANSI C edition), the reference
manual states (paragraphs 7.9 and 7.10) that pointer comparison is
undefined for pointers that do not point to the same object.

So if we have

const char * foo = "foo" , * bar = "bar" ;
int foobar = ( foo == bar ) ;

would it mean that foobar is undefined?

I knew that relational operators (<,<=,>=,>) cannot be used on pointers
to different objects, but how about equality operators ==,!= ?
I think you've found an error in K&R2. (BTW, it's "The C Programming
Language", not C++.) It's not mentioned in the errata at
<http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html> either.


I don't see any error in what you've posted, except for a probable
typo.
Section A7.9, "Relational Operators", discusses the "<", ">", "<=",
and ">=" operators. It says, in part:

Pointers comparison is defined only for parts of the same object:
[...] Otherwise, pointer comparison is undefined.
Shouldn't that read "Pointer comparison is..."? Did you make any
more serious typos? (It matters. ;-)
Anyway, that excerpt states explicitly that the behavior of the
following code is well-defined:

int bar[3];
(&bar[1] >= bar+2);

because '&bar[1]' and 'bar+2' point to parts of the same object. That
is, they both point to parts of the object 'bar', which is an array[3]
of int.
Section A7.10, "Equality Operators", discusses the "==" and "!="
operators. It says, in part:

The equality operators follow the same rules as the relational
operators, but permit additional possibilities: a pointer may be
compared to a constant integral expression with value 0, or to a
pointer to void. See section A6.6.
Looks good to me.
(Section A6.6 doesn't address the issue of comparing pointers to
distinct objects for equality.)

The corresponding sections in the C90 and C99 standard say that
relational operators on pointers to distinct objects cause undefined
behavior (except perhaps in some obscure circumstances involving
objects that happen to be adjacent in memory),
Nothing obscure about that circumstance! :) IIRC, the Standard
explicitly allows

int i;
int j;
printf("%d\n", &i+1 == &j)

to print "1", if j follows i in memory, even though &i+1 and &j point
to parts of different objects (&i points to the end of the object i,
and &j points to the object j). I don't recall any similar language
about relational operators, since the case

(&i < &j)

is explicitly covered by "undefined behavior" anyway, and can print 1,
or 0, or 42, or whatever it likes.
but doesn't make a
similar statement about equality operators, implying that equality
comparison of pointers to distinct objects is well-defined (and yields
the value 0).
Except in the circumstances above. I think you're right.
I hesitate to suggest that the creators of the language got something
like this wrong; it can happen, but I'm hardly immune to making
mistakes myself. I encourage other readers to check my interpretation
and point out whether I've missed something or K&R have.


So, what do you think K&R missed? It all looks there to me.

-Arthur

Nov 14 '05 #29
In article <j_****************@typhoon.bart.nl>,
Ike Naar <no****@nospam.invalid> wrote:
Christian Bau <ch***********@cbau.freeserve.co.uk> wrote:

: Ike Naar <no****@nospam.invalid> wrote:
:> In K&R "The C++ programming language (2nd ANSI C edition), the reference
:> manual states (paragraphs 7.9 and 7.10) that pointer comparison is
:> undefined for pointers that do not point to the same object.

: < <= > >= cannot be legally used on pointers to different objects; ==
: and != can. So either the book you mentioned is wrong, or you missed
: something when you read it. You might want to re-read it and see if it
: mentions "relational operators" and "equality operators".

Thanks for your response.

Paragraph 7.9 describes relational operators and explains how these
operators can only be used on pointers pointing to the same object.
Then it is exactly as the C Standard says. Relational operators must
_not_ be used to compare pointers to different objects or compare any
pointer to a NULL pointer, equality operators are perfectly legal to
compare pointers to different objects and NULL pointers.

So (&foo == &bar) is legal, (&foo == NULL) is legal, (&foo >= &bar) is
not legal, (&foo >= NULL) is not legal, and even (NULL >= NULL) is not
legal, even though NULL == NULL and if x == y then you would expect x >=
y to be true.
Paragraph 7.10 describes equality operators, and describes them as
analogous to relational operators, except that equality operators can
also be used to compare a pointer to an object and the null pointer.

: If you are
: sure you don't misunderstand anything, you should probably post a bit
: more literally from that book.

I don't have the book at hand now, but I can quote the paragraphs when
I get back to work in the morning.

Nov 14 '05 #30
In article <j_****************@typhoon.bart.nl>,
Ike Naar <no****@nospam.invalid> wrote:
Christian Bau <ch***********@cbau.freeserve.co.uk> wrote:

: Ike Naar <no****@nospam.invalid> wrote:
:> In K&R "The C++ programming language (2nd ANSI C edition), the reference
:> manual states (paragraphs 7.9 and 7.10) that pointer comparison is
:> undefined for pointers that do not point to the same object.

: < <= > >= cannot be legally used on pointers to different objects; ==
: and != can. So either the book you mentioned is wrong, or you missed
: something when you read it. You might want to re-read it and see if it
: mentions "relational operators" and "equality operators".

Thanks for your response.

Paragraph 7.9 describes relational operators and explains how these
operators can only be used on pointers pointing to the same object.
Then it is exactly as the C Standard says. Relational operators must
_not_ be used to compare pointers to different objects or compare any
pointer to a NULL pointer, equality operators are perfectly legal to
compare pointers to different objects and NULL pointers.

So (&foo == &bar) is legal, (&foo == NULL) is legal, (&foo >= &bar) is
not legal, (&foo >= NULL) is not legal, and even (NULL >= NULL) is not
legal, even though NULL == NULL and if x == y then you would expect x >=
y to be true.
Paragraph 7.10 describes equality operators, and describes them as
analogous to relational operators, except that equality operators can
also be used to compare a pointer to an object and the null pointer.

: If you are
: sure you don't misunderstand anything, you should probably post a bit
: more literally from that book.

I don't have the book at hand now, but I can quote the paragraphs when
I get back to work in the morning.

Nov 14 '05 #31
In article <Uq****************@typhoon.bart.nl>,
Ike Naar <no****@nospam.invalid> wrote:
Jeremy Yallop <je****@jdyallop.freeserve.co.uk> wrote:
: K&R, in A7.9, says:
: "Pointer comparison is defined only for parts of the same object:
: [...] if the pointers refer to members of an array, the comparison
: is equivalent to comparison of the corresponding subscripts."
: [...]. The undefined case is when the
: pointers are to entirely distinct objects:
: int a, b;
: &a == &b; /* okay */

How could this be OK, if &a and &b are pointing to distinct objects?
It is an equality operator, not a relational operator. The rules are
different for equality operators and relational operators.
: &a > &b; /* undefined */

: It's the behaviour that's undefined, not just the result, so the
: comparison could cause your program to crash (in theory, at least).

: Jeremy.

Nov 14 '05 #32
In article <Uq****************@typhoon.bart.nl>,
Ike Naar <no****@nospam.invalid> wrote:
Jeremy Yallop <je****@jdyallop.freeserve.co.uk> wrote:
: K&R, in A7.9, says:
: "Pointer comparison is defined only for parts of the same object:
: [...] if the pointers refer to members of an array, the comparison
: is equivalent to comparison of the corresponding subscripts."
: [...]. The undefined case is when the
: pointers are to entirely distinct objects:
: int a, b;
: &a == &b; /* okay */

How could this be OK, if &a and &b are pointing to distinct objects?
It is an equality operator, not a relational operator. The rules are
different for equality operators and relational operators.
: &a > &b; /* undefined */

: It's the behaviour that's undefined, not just the result, so the
: comparison could cause your program to crash (in theory, at least).

: Jeremy.

Nov 14 '05 #33
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> writes:
On Tue, 6 Apr 2004, Keith Thompson wrote: [...]
I think you've found an error in K&R2. (BTW, it's "The C Programming
Language", not C++.) It's not mentioned in the errata at
<http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html> either.


I don't see any error in what you've posted, except for a probable
typo.
Section A7.9, "Relational Operators", discusses the "<", ">", "<=",
and ">=" operators. It says, in part:

Pointers comparison is defined only for parts of the same object:
[...] Otherwise, pointer comparison is undefined.


Shouldn't that read "Pointer comparison is..."? Did you make any
more serious typos? (It matters. ;-)


At the moment, I'm at home and my copy of K&R2 is at the office.
Since you can't cut-and-paste dead trees (well, I suppose you can if
you take it literally), I'll have to do this from memory. Yes, I'm
sure I meant "Pointer comparison is..."; I'll go back and proofread
the rest when I get a chance.
Anyway, that excerpt states explicitly that the behavior of the
following code is well-defined:

int bar[3];
(&bar[1] >= bar+2);

because '&bar[1]' and 'bar+2' point to parts of the same object. That
is, they both point to parts of the object 'bar', which is an array[3]
of int.
Agreed.
Section A7.10, "Equality Operators", discusses the "==" and "!="
operators. It says, in part:

The equality operators follow the same rules as the relational
operators, but permit additional possibilities: a pointer may be
compared to a constant integral expression with value 0, or to a
pointer to void. See section A6.6.


Looks good to me.


Almost; see below.
(Section A6.6 doesn't address the issue of comparing pointers to
distinct objects for equality.)

The corresponding sections in the C90 and C99 standard say that
relational operators on pointers to distinct objects cause undefined
behavior (except perhaps in some obscure circumstances involving
objects that happen to be adjacent in memory),


Nothing obscure about that circumstance! :) IIRC, the Standard
explicitly allows

int i;
int j;
printf("%d\n", &i+1 == &j)

to print "1", if j follows i in memory, even though &i+1 and &j point
to parts of different objects (&i points to the end of the object i,
and &j points to the object j). I don't recall any similar language
about relational operators, since the case

(&i < &j)

is explicitly covered by "undefined behavior" anyway, and can print 1,
or 0, or 42, or whatever it likes.


One might assume that if &i+1 == &j is true, then &i+1 <= &j and
&i+1 >= &j are also true, and &i+1 < &j and &i+1 > &j are false, but
yes, since the standard doesn't say so I suppose it's covered by
"undefined behavior". But this is not the main point.
but doesn't make a
similar statement about equality operators, implying that equality
comparison of pointers to distinct objects is well-defined (and yields
the value 0).


Except in the circumstances above. I think you're right.

[...] So, what do you think K&R missed? It all looks there to me.


But here's the problem. Suppose x and y are distinct objects of the
same type that do not happen to be adjacent. It's clear from the C90
and C99 standards and from K&R2 that the expression &x < &y invokes
undefined behavior (K&R1 merely says it's not portable). In the C90
and C99 standards, the statement about undefined behavior occurs in
the description of relational operators, but not in the description of
equality operators, so the expression &x == &y is well-defined (and
yields 0). In K&R2, the section on relational operators says that
&x < &y is undefined, but the section on equality operators refers
to the section on relational operators:

The equality operators follow the same rules as the relational
operators, but permit additional possibilities: a pointer may be
compared to a constant integral expression with value 0, or to a
pointer to void. See section A6.6.

implying that &x == &y is undefined, just as &x < &y is.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #34
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> writes:
On Tue, 6 Apr 2004, Keith Thompson wrote: [...]
I think you've found an error in K&R2. (BTW, it's "The C Programming
Language", not C++.) It's not mentioned in the errata at
<http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html> either.


I don't see any error in what you've posted, except for a probable
typo.
Section A7.9, "Relational Operators", discusses the "<", ">", "<=",
and ">=" operators. It says, in part:

Pointers comparison is defined only for parts of the same object:
[...] Otherwise, pointer comparison is undefined.


Shouldn't that read "Pointer comparison is..."? Did you make any
more serious typos? (It matters. ;-)


At the moment, I'm at home and my copy of K&R2 is at the office.
Since you can't cut-and-paste dead trees (well, I suppose you can if
you take it literally), I'll have to do this from memory. Yes, I'm
sure I meant "Pointer comparison is..."; I'll go back and proofread
the rest when I get a chance.
Anyway, that excerpt states explicitly that the behavior of the
following code is well-defined:

int bar[3];
(&bar[1] >= bar+2);

because '&bar[1]' and 'bar+2' point to parts of the same object. That
is, they both point to parts of the object 'bar', which is an array[3]
of int.
Agreed.
Section A7.10, "Equality Operators", discusses the "==" and "!="
operators. It says, in part:

The equality operators follow the same rules as the relational
operators, but permit additional possibilities: a pointer may be
compared to a constant integral expression with value 0, or to a
pointer to void. See section A6.6.


Looks good to me.


Almost; see below.
(Section A6.6 doesn't address the issue of comparing pointers to
distinct objects for equality.)

The corresponding sections in the C90 and C99 standard say that
relational operators on pointers to distinct objects cause undefined
behavior (except perhaps in some obscure circumstances involving
objects that happen to be adjacent in memory),


Nothing obscure about that circumstance! :) IIRC, the Standard
explicitly allows

int i;
int j;
printf("%d\n", &i+1 == &j)

to print "1", if j follows i in memory, even though &i+1 and &j point
to parts of different objects (&i points to the end of the object i,
and &j points to the object j). I don't recall any similar language
about relational operators, since the case

(&i < &j)

is explicitly covered by "undefined behavior" anyway, and can print 1,
or 0, or 42, or whatever it likes.


One might assume that if &i+1 == &j is true, then &i+1 <= &j and
&i+1 >= &j are also true, and &i+1 < &j and &i+1 > &j are false, but
yes, since the standard doesn't say so I suppose it's covered by
"undefined behavior". But this is not the main point.
but doesn't make a
similar statement about equality operators, implying that equality
comparison of pointers to distinct objects is well-defined (and yields
the value 0).


Except in the circumstances above. I think you're right.

[...] So, what do you think K&R missed? It all looks there to me.


But here's the problem. Suppose x and y are distinct objects of the
same type that do not happen to be adjacent. It's clear from the C90
and C99 standards and from K&R2 that the expression &x < &y invokes
undefined behavior (K&R1 merely says it's not portable). In the C90
and C99 standards, the statement about undefined behavior occurs in
the description of relational operators, but not in the description of
equality operators, so the expression &x == &y is well-defined (and
yields 0). In K&R2, the section on relational operators says that
&x < &y is undefined, but the section on equality operators refers
to the section on relational operators:

The equality operators follow the same rules as the relational
operators, but permit additional possibilities: a pointer may be
compared to a constant integral expression with value 0, or to a
pointer to void. See section A6.6.

implying that &x == &y is undefined, just as &x < &y is.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #35
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
I think you've found an error in K&R2. (BTW, it's "The C Programming
Not really. But the text really needs to be improved.
Language", not C++.) It's not mentioned in the errata at
<http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html> either.

Section A7.9, "Relational Operators", discusses the "<", ">", "<=",
and ">=" operators. It says, in part:

Pointers comparison is defined only for parts of the same object:
[...] Otherwise, pointer comparison is undefined.

Section A7.10, "Equality Operators", discusses the "==" and "!="
operators. It says, in part:

The equality operators follow the same rules as the relational
operators, but permit additional possibilities: a pointer may be
compared to a constant integral expression with value 0, or to a
pointer to void. See section A6.6.

(Section A6.6 doesn't address the issue of comparing pointers to
distinct objects for equality.)

The corresponding sections in the C90 and C99 standard say that
relational operators on pointers to distinct objects cause undefined
behavior (except perhaps in some obscure circumstances involving
objects that happen to be adjacent in memory), but doesn't make a
similar statement about equality operators, implying that equality
comparison of pointers to distinct objects is well-defined (and yields
the value 0).

I hesitate to suggest that the creators of the language got something
like this wrong; it can happen, but I'm hardly immune to making
mistakes myself. I encourage other readers to check my interpretation
and point out whether I've missed something or K&R have.


The key is in the "or to a pointer to void" words in A7.10. It means
you can compare a pointer to an object and a pointer to non-object for
equality, so the restriction that both pointers must point inside the
same object no longer applies. It's still not immediately obvious that
you can compare for equality object pointers that point to different
objects, but, since p == (void *)q is allowed regardless of where q
points (the text under discussion doesn't impose restrictions on the void
pointer operand), it follows that p == q should be valid, too (assuming
that the types of p and q allow direct comparison for equality).

As I said at the beginning, the text is far from optimal (or even
"clear enough", in the C committee lingo) and my interpretation was
heavily influenced by the fact that I already knew the right answer.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #36
In <ln************@nuthaus.mib.org> Keith Thompson <ks***@mib.org> writes:
I think you've found an error in K&R2. (BTW, it's "The C Programming
Not really. But the text really needs to be improved.
Language", not C++.) It's not mentioned in the errata at
<http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html> either.

Section A7.9, "Relational Operators", discusses the "<", ">", "<=",
and ">=" operators. It says, in part:

Pointers comparison is defined only for parts of the same object:
[...] Otherwise, pointer comparison is undefined.

Section A7.10, "Equality Operators", discusses the "==" and "!="
operators. It says, in part:

The equality operators follow the same rules as the relational
operators, but permit additional possibilities: a pointer may be
compared to a constant integral expression with value 0, or to a
pointer to void. See section A6.6.

(Section A6.6 doesn't address the issue of comparing pointers to
distinct objects for equality.)

The corresponding sections in the C90 and C99 standard say that
relational operators on pointers to distinct objects cause undefined
behavior (except perhaps in some obscure circumstances involving
objects that happen to be adjacent in memory), but doesn't make a
similar statement about equality operators, implying that equality
comparison of pointers to distinct objects is well-defined (and yields
the value 0).

I hesitate to suggest that the creators of the language got something
like this wrong; it can happen, but I'm hardly immune to making
mistakes myself. I encourage other readers to check my interpretation
and point out whether I've missed something or K&R have.


The key is in the "or to a pointer to void" words in A7.10. It means
you can compare a pointer to an object and a pointer to non-object for
equality, so the restriction that both pointers must point inside the
same object no longer applies. It's still not immediately obvious that
you can compare for equality object pointers that point to different
objects, but, since p == (void *)q is allowed regardless of where q
points (the text under discussion doesn't impose restrictions on the void
pointer operand), it follows that p == q should be valid, too (assuming
that the types of p and q allow direct comparison for equality).

As I said at the beginning, the text is far from optimal (or even
"clear enough", in the C committee lingo) and my interpretation was
heavily influenced by the fact that I already knew the right answer.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #37
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> writes:
On Tue, 6 Apr 2004, Keith Thompson wrote: [...]
Section A7.9, "Relational Operators", discusses the "<", ">", "<=",
and ">=" operators. It says, in part:

Pointers comparison is defined only for parts of the same object:
[...] Otherwise, pointer comparison is undefined.


Shouldn't that read "Pointer comparison is..."? Did you make any
more serious typos? (It matters. ;-)


I just re-checked what I posted previously against my copy of K&R2.
I believe that typing "Pointers comparison" rather than "Pointer
comparison" is the only transcription error I made.

I have the first printing, with "Based on Draft-Proposed ANSI C"
on the cover. The text in question is not relevantly affected
by the on-line errata, though there is one change in a part of
that section that I didn't quote:

On p. 206, A7.9, about relational operators: ``Pointers to objects
of the same type may be compared...'' is changed to ``Pointers to
object of the same type >(ignoring any qualifiers)< may be
compared...''.
Anyway, that excerpt states explicitly that the behavior of the
following code is well-defined:

int bar[3];
(&bar[1] >= bar+2);

because '&bar[1]' and 'bar+2' point to parts of the same object. That
is, they both point to parts of the object 'bar', which is an array[3]
of int.
Section A7.10, "Equality Operators", discusses the "==" and "!="
operators. It says, in part:

The equality operators follow the same rules as the relational
operators, but permit additional possibilities: a pointer may be
compared to a constant integral expression with value 0, or to a
pointer to void. See section A6.6.


Looks good to me.
(Section A6.6 doesn't address the issue of comparing pointers to
distinct objects for equality.)

The corresponding sections in the C90 and C99 standard say that
relational operators on pointers to distinct objects cause undefined
behavior (except perhaps in some obscure circumstances involving
objects that happen to be adjacent in memory),


--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #38
Da*****@cern.ch (Dan Pop) writes:
[...]
The key is in the "or to a pointer to void" words in A7.10. It means
you can compare a pointer to an object and a pointer to non-object for
equality, so the restriction that both pointers must point inside the
same object no longer applies. It's still not immediately obvious that
you can compare for equality object pointers that point to different
objects, but, since p == (void *)q is allowed regardless of where q
points (the text under discussion doesn't impose restrictions on the void
pointer operand), it follows that p == q should be valid, too (assuming
that the types of p and q allow direct comparison for equality).


Sorry, I'm not convinced. Someone who hasn't assumed that p == q is
valid is not likely to infer it from the pointer-to-void rule. If the
"additional possibilities" clause is meant to be exhaustive, it's
pretty clear (to me) that it *deosn't* cover p == q, where p and q are
pointers to distinct non-adjacent objects; neither p nor q is a
pointer to void.

Given that p == (void*)q is valid, it certainly makes sense that p == q
*should* be valid, but it's not stated, and there are too many other
places in the language where the "it makes sense that it should be
valid" rule breaks down.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #39
Christian Bau <ch***********@cbau.freeserve.co.uk> writes:
In article <j_****************@typhoon.bart.nl>,
Ike Naar <no****@nospam.invalid> wrote:
Christian Bau <ch***********@cbau.freeserve.co.uk> wrote:

: Ike Naar <no****@nospam.invalid> wrote:
:> In K&R "The C++ programming language (2nd ANSI C edition), the reference
:> manual states (paragraphs 7.9 and 7.10) that pointer comparison is
:> undefined for pointers that do not point to the same object.

: < <= > >= cannot be legally used on pointers to different objects; ==
: and != can. So either the book you mentioned is wrong, or you missed
: something when you read it. You might want to re-read it and see if it
: mentions "relational operators" and "equality operators".

Thanks for your response.

Paragraph 7.9 describes relational operators and explains how these
operators can only be used on pointers pointing to the same object.
Then it is exactly as the C Standard says. Relational operators must
_not_ be used to compare pointers to different objects or compare any
pointer to a NULL pointer,


Agreed.
equality operators are perfectly legal to
compare pointers to different objects and NULL pointers.


I agree (that's clearly the intent, and it says so in the standard),
but K&R2 just doesn't say so.

I think we're all in agreement that relational operators (<, <=, >,>=)
between pointers to distinct non-adjacent objects invoke undefined
behavior, and that K&R2 A7.9 says so sufficently clearly, so I won't
re-type that section.

Here's the entirety of section A7.10 of K&R2 (first printing, but
there are no errata for that section). I've double checked for typos,
but I can't guarantee perfection. I haven't tried to reproduce
italics or bold-face, and the layout differs but not significantly.
I'll use "[section]" for the section symbol (that funky character that
looks like two intertwined S's).

A7.10 Equality Operators

equality-expression:
relational-expression
equality-expression == relational-expression
equality-expression != relational-expression

The == (equal to) and the != (not equal to) operators are analogous
to the relational operators except for their lower precedence.
(Thus a<b == c<d is 1 whenever a<b and c<d have the same
truth-value.)

The equality operators follow the same rules as the relational
operators, but permit additional possibilities: a pointer may
be compared to a constant integral expression with value 0,
or to a pointer to void. See [section]A6.6.

I presume that the listed "additional possibilities" are intended to
be exhaustive; this is a reference manual, after all.

Suppose p and q are pointers to distinct non-adjacent objects of the
same type. Where in A7.10 (or anywhere else in Appendix A) is it
stated that, although p < q is undefined, p == q is well-defined?
(Pretend that you don't already know that before reading it.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #40
Keith Thompson <ks***@mib.org> writes:
[...]
Given that p == (void*)q is valid, it certainly makes sense that p == q
*should* be valid, but it's not stated, and there are too many other
places in the language where the "it makes sense that it should be
valid" rule breaks down.


I sent an e-mail message to Dennis Ritchie pointing out this minor
oversight in section A7.10 of K&R2. (I credited Ike Naar for finding
it.) He agrees that it's an error, and will add it to the errata.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #41

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
by: __PPS__ | last post by:
Hello everybody in a quiz I had a question about dangling pointer: "What a dangling pointer is and the danger of using it" My answer was: "dangling pointer is a pointer that points to some...
22
by: Ike Naar | last post by:
In K&R "The C++ programming language (2nd ANSI C edition), the reference manual states (paragraphs 7.9 and 7.10) that pointer comparison is undefined for pointers that do not point to the same...
26
by: Meenu | last post by:
Hi, Can two different far pointers contain two different addresses but refer to the same location in memory?
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.