pointer equality

Discussion in 'C Programming' started by Ike Naar, Apr 6, 2004.

  1. Ike Naar

    Ike Naar Guest

    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
    Ike Naar, Apr 6, 2004
    #1
    1. Advertising

  2. In article <ZeFcc.874$%>,
    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 ==,!= ?


    < <= > >= 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.
    Christian Bau, Apr 6, 2004
    #2
    1. Advertising

  3. Ike Naar

    Leor Zolman Guest

    On Tue, 06 Apr 2004 21:25:13 GMT, 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?


    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
    Leor Zolman, Apr 6, 2004
    #3
  4. Ike Naar

    Ike Naar Guest

    Christian Bau <> wrote:

    : 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.

    : < <= > >= 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
    Ike Naar, Apr 6, 2004
    #4
  5. Ike Naar

    Ike Naar Guest

    Leor Zolman <> wrote:

    : On Tue, 06 Apr 2004 21:25:13 GMT, 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.

    : 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.
    Ike Naar, Apr 6, 2004
    #5
  6. Ike Naar wrote:
    > Leor Zolman <> wrote:
    >
    >: On Tue, 06 Apr 2004 21:25:13 GMT, 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.
    >
    >: 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.
    Jeremy Yallop, Apr 6, 2004
    #6
  7. Leor Zolman <> writes:

    > On Tue, 06 Apr 2004 21:25:13 GMT, Ike Naar <> 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. \_/
    Martin Dickopp, Apr 6, 2004
    #7
  8. Ike Naar

    Ike Naar Guest

    Jeremy Yallop <> 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
    Ike Naar, Apr 6, 2004
    #8
  9. Ike Naar

    pete Guest

    Ike Naar wrote:
    >
    > Jeremy Yallop <> 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
    pete, Apr 7, 2004
    #9
  10. "Ike Naar" <> a écrit dans le message de
    news:UqGcc.878$%...

    Hi,

    > Jeremy Yallop <> 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
    Régis Troadec, Apr 7, 2004
    #10
  11. Ike Naar <> 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) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    Schroedinger does Shakespeare: "To be *and* not to be"
    Keith Thompson, Apr 7, 2004
    #11
  12. 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).
    E. Robert Tisdale, Apr 7, 2004
    #12
  13. Ike Naar

    Ike Naar Guest

    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 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) <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
    Ike Naar, Apr 7, 2004
    #13
  14. "E. Robert Tisdale" <> 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) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    Schroedinger does Shakespeare: "To be *and* not to be"
    Keith Thompson, Apr 7, 2004
    #14
  15. On Tue, 6 Apr 2004, Keith Thompson wrote:
    >
    > Ike Naar <> 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
    Arthur J. O'Dwyer, Apr 7, 2004
    #15
  16. In article <j_Fcc.876$%>,
    Ike Naar <> wrote:

    > Christian Bau <> wrote:
    >
    > : 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.
    >
    > : < <= > >= 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.
    Christian Bau, Apr 7, 2004
    #16
  17. In article <UqGcc.878$%>,
    Ike Naar <> wrote:

    > Jeremy Yallop <> 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.
    Christian Bau, Apr 7, 2004
    #17
  18. "Arthur J. O'Dwyer" <> 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) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    Schroedinger does Shakespeare: "To be *and* not to be"
    Keith Thompson, Apr 7, 2004
    #18
  19. Ike Naar

    Dan Pop Guest

    In <> Keith Thompson <> 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:
    Dan Pop, Apr 7, 2004
    #19
  20. "Arthur J. O'Dwyer" <> 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) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    Schroedinger does Shakespeare: "To be *and* not to be"
    Keith Thompson, Apr 8, 2004
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. sb
    Replies:
    4
    Views:
    427
    Nick Hounsome
    Apr 3, 2004
  2. sb
    Replies:
    2
    Views:
    384
    Nick Hounsome
    Apr 3, 2004
  3. Replies:
    10
    Views:
    669
    Chris Torek
    Feb 4, 2005
  4. jimjim
    Replies:
    16
    Views:
    822
    Jordan Abel
    Mar 28, 2006
  5. Shao Miller

    Pointer Equality for Different Array Objects

    Shao Miller, Feb 3, 2012, in forum: C Programming
    Replies:
    11
    Views:
    393
    Shao Miller
    Feb 6, 2012
Loading...

Share This Page