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 svefg 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
     
    Francois Grieu, Nov 8, 2005
    #1
    1. Advertising

  2. Francois Grieu

    Richard Bos 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; }
    >
    > #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 svefg bar vf pbeerpg.


    What's wrong with the third? The error in the second is clear; but the
    third generates a+(1-1) and a+(2-1), that is, a+0 and a+1, neither of
    which is a problem.

    Richard
     
    Richard Bos, Nov 8, 2005
    #2
    1. Advertising

  3. In article <4all.nl>,
    (Richard Bos) 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; }
    > >
    > > #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 svefg bar vf pbeerpg.

    >
    > What's wrong with the third?


    Nothing. The spoiler was wrong..

    > The error in the second is clear;


    Yes. The first is wrong too, because a+2 is undefined.

    Francois Grieu
     
    Francois Grieu, Nov 9, 2005
    #3
  4. Francois Grieu

    Richard Bos Guest

    Francois Grieu <> wrote:

    > In article <4all.nl>,
    > (Richard Bos) 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; }
    > > >
    > > > #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 svefg bar vf pbeerpg.

    > >
    > > What's wrong with the third?

    >
    > Nothing. The spoiler was wrong..
    >
    > > The error in the second is clear;

    >
    > Yes. The first is wrong too, because a+2 is undefined.


    No. The first is correct. You are allowed to _calculate_ the address one
    past the end of an array. What you can't do is a. dereference said
    one-past array or b. calculate any addresses beyond that.

    This can be useful for the termination condition of loops over arrays.

    Richard
     
    Richard Bos, Nov 9, 2005
    #4
  5. Francois Grieu

    pete Guest

    Richard Bos wrote:
    >
    > Francois Grieu <> wrote:
    >
    > > In article <4all.nl>,
    > > (Richard Bos) 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; }
    > > > >
    > > > > #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 svefg bar vf pbeerpg.
    > > >
    > > > What's wrong with the third?

    > >
    > > Nothing. The spoiler was wrong..
    > >
    > > > The error in the second is clear;

    > >
    > > Yes. The first is wrong too, because a+2 is undefined.

    >
    > No. The first is correct.
    > You are allowed to _calculate_ the address one
    > past the end of an array. What you can't do is a. dereference said
    > one-past array or b. calculate any addresses beyond that.
    >
    > This can be useful for the termination condition of loops over arrays.


    The third one would have been wrong if the initial value
    of j was zero. On systems where unsigned char promotes to unsigned,
    (j-1) would have been UINT_MAX.

    --
    pete
     
    pete, Nov 9, 2005
    #5
    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:
    532
  2. Marc Schellens

    Iterator/pointer arithmetic

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

    Is pointer arithmetic associative?

    Francois Grieu, Nov 8, 2005, in forum: C Programming
    Replies:
    6
    Views:
    349
    Keith Thompson
    Nov 14, 2005
  5. desktop
    Replies:
    5
    Views:
    404
    James Kanze
    Jun 26, 2007
Loading...

Share This Page