By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,943 Members | 1,260 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,943 IT Pros & Developers. It's quick & easy.

Is pointer arithmetic associative?

P: n/a
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 !]
Nov 15 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Francois Grieu <fg****@francenet.fr> 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
Nov 15 '05 #2

P: n/a
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.
Nov 15 '05 #3

P: n/a
On 2005-11-14, Simon Biber <ne**@ralmin.cc> 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)
Nov 15 '05 #4

P: n/a
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.
Nov 15 '05 #5

P: n/a
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
Nov 15 '05 #6

P: n/a
pete <pf*****@mindspring.com> 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) ks***@mib.org <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.
Nov 15 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.