Is pointer arithmetic associative?

Discussion in 'C Programming' started by Francois Grieu, Nov 8, 2005.

  1. Are these programs correct ?

    #include <stdio.h>
    unsigned char a[2] = {1,2};
    int main(void) {
    unsigned char j;
    for(j=1; j<=2; ++j)
    printf("%u\n", *( a+j-1 ));
    return 0; }


    #include <stdio.h>
    unsigned char a[2] = {1,2};
    int main(void) {
    unsigned char j;
    for(j=1; j<=2; ++j)
    printf("%u\n", *( a-1+j ));
    return 0; }


    #include <stdio.h>
    unsigned char a[2] = {1,2};
    int main(void) {
    unsigned char j;
    for(j=1; j<=2; ++j)
    printf("%u\n", *( a+(j-1) ));
    return 0; }

    rot-13 spoiler: bayl gur ynfg bar vf pbeerpg.


    One compiler I use generates correct and tight code for the
    second form; but it fails for *(-1+a+j) [not due to an
    architectural restriction, but due to a plain compiler bug].

    Isn't it a shame C programming is so complex ? Given that on
    most platforms, pointer arithmetic is associative, and so many
    programs out there assume it blindly, is not it time for a
    future C standard to waive these restrictions on pointer
    associativity in at least a branch of the standard, say with
    a predefined constant __ASSOCIATIVE_POINTERS__ ?


    Francois Grieu
    [reposted with fixed spoiler !]
     
    Francois Grieu, Nov 8, 2005
    #1
    1. Advertising

  2. Francois Grieu

    Marc Boyer Guest

    Francois Grieu <> a écrit :
    > Isn't it a shame C programming is so complex ?


    Yes it is, but is there a better solution ?

    > Given that on
    > most platforms, pointer arithmetic is associative, and so many
    > programs out there assume it blindly, is not it time for a
    > future C standard to waive these restrictions on pointer
    > associativity in at least a branch of the standard, say with
    > a predefined constant __ASSOCIATIVE_POINTERS__ ?


    Did you thought to all implications of your proposition.
    It means that you should define a notion of something like
    'non-expression', because, you goal for associativity
    is to be able to write
    char*p ="foo";
    *(p-1+1)
    It means that p-1 is no more an expression (invalid),
    but p+1-1 is one...
    That is to say, p-1+1 does not mean (p-1)+1 but
    p+(-1+1).
    And what about (--p+1), (-1+p+1), (1+p-1) ?

    Marc Boyer
     
    Marc Boyer, Nov 8, 2005
    #2
    1. Advertising

  3. Francois Grieu

    Simon Biber Guest

    Francois Grieu wrote:
    > Are these programs correct ?
    >
    > #include <stdio.h>
    > unsigned char a[2] = {1,2};
    > int main(void) {
    > unsigned char j;
    > for(j=1; j<=2; ++j)
    > printf("%u\n", *( a+j-1 ));
    > return 0; }


    No problems here, it is acceptable to calculate a pointer to one element
    past the end of an array.


    > #include <stdio.h>
    > unsigned char a[2] = {1,2};
    > int main(void) {
    > unsigned char j;
    > for(j=1; j<=2; ++j)
    > printf("%u\n", *( a-1+j ));
    > return 0; }


    This one is wrong, it is not acceptable to calculate a pointer to one
    element before the beginning of an array.


    > #include <stdio.h>
    > unsigned char a[2] = {1,2};
    > int main(void) {
    > unsigned char j;
    > for(j=1; j<=2; ++j)
    > printf("%u\n", *( a+(j-1) ));
    > return 0; }


    This one is fine, you never calculate an invalid pointer at all.

    > rot-13 spoiler: bayl gur ynfg bar vf pbeerpg.


    Undeciphered: only the last one is correct.

    No, the first one is fine too.

    > One compiler I use generates correct and tight code for the
    > second form; but it fails for *(-1+a+j) [not due to an
    > architectural restriction, but due to a plain compiler bug].


    There is no "correct" code for the second; both the second and *(-1+a+j)
    have undefined behaviour, for the same reason.

    > Isn't it a shame C programming is so complex ? Given that on
    > most platforms, pointer arithmetic is associative, and so many
    > programs out there assume it blindly, is not it time for a
    > future C standard to waive these restrictions on pointer
    > associativity in at least a branch of the standard, say with
    > a predefined constant __ASSOCIATIVE_POINTERS__ ?


    When you speak of the associativity of "pointer arithmetic", you are
    really conflating two things: integer arithmetic and pointer arithmetic.
    Pointer arithmetic cannot be associative, because the syntax does not
    even allow constructs like
    pointer1 op pointer2 op pointer3
    (where both 'op's are the same operator). If op were '+', then it is a
    constraint violation as two pointers cannot be added together. If op
    were '-', the result of two pointers being subtracted is an integer,
    from which you cannot subtract a pointer.

    Remember that there are no restrictions on the behaviour of a program
    with undefined behaviour; it may behave as you expect, or not.

    --
    Simon.
     
    Simon Biber, Nov 14, 2005
    #3
  4. Francois Grieu

    Jordan Abel Guest

    On 2005-11-14, Simon Biber <> wrote:
    > Francois Grieu wrote:
    >> Are these programs correct ?
    >>
    >> #include <stdio.h>
    >> unsigned char a[2] = {1,2};
    >> int main(void) {
    >> unsigned char j;
    >> for(j=1; j<=2; ++j)
    >> printf("%u\n", *( a+j-1 ));
    >> return 0; }

    >
    > No problems here, it is acceptable to calculate a pointer to one element
    > past the end of an array.
    >
    >
    >> #include <stdio.h>
    >> unsigned char a[2] = {1,2};
    >> int main(void) {
    >> unsigned char j;
    >> for(j=1; j<=2; ++j)
    >> printf("%u\n", *( a-1+j ));
    >> return 0; }

    >
    > This one is wrong, it is not acceptable to calculate a pointer to one
    > element before the beginning of an array.


    Note that a-(1-j), however, would be correct, i believe.

    [more stuff snipped]

    >> Isn't it a shame C programming is so complex ? Given that on
    >> most platforms, pointer arithmetic is associative, and so many
    >> programs out there assume it blindly, is not it time for a
    >> future C standard to waive these restrictions on pointer
    >> associativity in at least a branch of the standard, say with
    >> a predefined constant __ASSOCIATIVE_POINTERS__ ?

    >
    > When you speak of the associativity of "pointer arithmetic", you are
    > really conflating two things: integer arithmetic and pointer arithmetic.
    > Pointer arithmetic cannot be associative, because the syntax does not
    > even allow constructs like
    > pointer1 op pointer2 op pointer3
    > (where both 'op's are the same operator). If op were '+', then it is a
    > constraint violation as two pointers cannot be added together. If op
    > were '-', the result of two pointers being subtracted is an integer,
    > from which you cannot subtract a pointer.
    >
    > Remember that there are no restrictions on the behaviour of a program
    > with undefined behaviour; it may behave as you expect, or not.


    It would be simple enough, though, to force compilers to collate all the
    integer components of a pointer arithmetic expression into a single
    value which is then added to the pointer, which is really what he is
    requesting.

    i.e. for arbitrary

    i1-i2+p+i3-i4, force that to become p+(i1-i2+i3-i4)
     
    Jordan Abel, Nov 14, 2005
    #4
  5. Francois Grieu

    Simon Biber Guest

    Jordan Abel wrote:
    > It would be simple enough, though, to force compilers to collate all the
    > integer components of a pointer arithmetic expression into a single
    > value which is then added to the pointer, which is really what he is
    > requesting.
    >
    > i.e. for arbitrary
    >
    > i1-i2+p+i3-i4, force that to become p+(i1-i2+i3-i4)


    Conversely, it's simple enough to ask programmers to follow this rule
    anyway, always putting the pointer at the beginning of such an expression.

    Anyone who wrote i1-i2+p+i3-i4 in a real program should be shot. Make it
    clear and self-descriptive. Having four different offsets added to a
    pointer is a little excessive.

    My worst so far is something like:

    unsigned short *
    get(unsigned short *array, int x, int y, int z)
    {
    return array + x
    + y * mapWidth
    + z * mapWidth * mapHeight;
    }

    Actually, it was C++ code and used references instead of pointers, but
    you get the idea.

    --
    Simon.
     
    Simon Biber, Nov 14, 2005
    #5
  6. Francois Grieu

    pete Guest

    Simon Biber wrote:
    > Jordan Abel wrote:


    >> i1-i2+p+i3-i4, force that to become p+(i1-i2+i3-i4)


    > Conversely, it's simple enough to ask programmers to follow this rule
    > anyway,
    > always putting the pointer at the beginning of such an expression.


    Actually,
    placing the pointer after a sequence of integer additions
    avoids problems better.

    (i1 + i2 + p) only depends on the final sum
    (p + i1 + i2) also depends on i1 being
    neither negative nor excessively large.

    --
    pete
     
    pete, Nov 14, 2005
    #6
  7. pete <> writes:
    > Simon Biber wrote:
    >> Jordan Abel wrote:

    >
    >>> i1-i2+p+i3-i4, force that to become p+(i1-i2+i3-i4)

    >
    >> Conversely, it's simple enough to ask programmers to follow this rule
    >> anyway,
    >> always putting the pointer at the beginning of such an expression.

    >
    > Actually,
    > placing the pointer after a sequence of integer additions
    > avoids problems better.
    >
    > (i1 + i2 + p) only depends on the final sum
    > (p + i1 + i2) also depends on i1 being
    > neither negative nor excessively large.


    p + (i1 + i2) is an improvement on both.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Nov 14, 2005
    #7
    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. a

    pointer arithmetic

    a, Sep 11, 2003, in forum: C++
    Replies:
    6
    Views:
    524
  2. Marc Schellens

    Iterator/pointer arithmetic

    Marc Schellens, Dec 5, 2003, in forum: C++
    Replies:
    15
    Views:
    850
    tom_usenet
    Dec 8, 2003
  3. joshc
    Replies:
    5
    Views:
    559
    Keith Thompson
    Mar 31, 2005
  4. Francois Grieu

    Is pointer arithmetic associative?

    Francois Grieu, Nov 8, 2005, in forum: C Programming
    Replies:
    4
    Views:
    614
  5. desktop
    Replies:
    5
    Views:
    388
    James Kanze
    Jun 26, 2007
Loading...

Share This Page