a[3] <===> *(a + 3) ???

K

KKramsch

How close to equivalent are the expressions

a[3]

and

*(a + 3)

?

Can they be used entirely interchangeably, or are there situations
in which one will be OK and the other one not?

Thanks!

Karl
 
D

dandelion

Can they be used entirely interchangeably, or are there situations
in which one will be OK and the other one not?

AFAIK they are fully equivalent. See the FAQ.
 
G

Goran Larsson

KKramsch said:
Can they be used entirely interchangeably, or are there situations
in which one will be OK and the other one not?

If "a" is a macro then the two forms may not be similar, e.g.

#define a p + 10 /* valid, but bad style */
 
L

Lew Pitcher

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
How close to equivalent are the expressions

a[3]

and

*(a + 3)

?

Can they be used entirely interchangeably, or are there situations
in which one will be OK and the other one not?

They are /so/ equivalent that it is as perfectly legal to write
3[a]
as it is to write
a[3]
or
*(a + 3)

All three expressions are equivalent and interchangable.

- --
Lew Pitcher
IT Consultant, Enterprise Data Systems,
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed are my own, not my employers')
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFBnLemagVFX4UWr64RAqTBAJ9nd0p582w+gBOsxPf3XhKn9JnsPACeJD7M
ayi3/N0NCRgSEKZhcXOx8vk=
=5xbh
-----END PGP SIGNATURE-----
 
I

Imanpreet Singh Arora

Goran said:
If "a" is a macro then the two forms may not be similar, e.g.

#define a p + 10 /* valid, but bad style */


Read the OP's question again

<quote>
How close to equivalent are the expressions

a[3]

and

*(a + 3)


<quote>

now
if

#define a p + 10

The the first one will be equal to


p + 10[3]?
 
P

pete

KKramsch said:
How close to equivalent are the expressions

a[3]

and

*(a + 3)

?

Can they be used entirely interchangeably, or are there situations
in which one will be OK and the other one not?

Add a pair of parentheses and they're exactly the same.

*((a) + 3) == a[3]
 
C

Charlie Gordon

pete said:
KKramsch said:
How close to equivalent are the expressions

a[3]

and

*(a + 3)

?

Can they be used entirely interchangeably, or are there situations
in which one will be OK and the other one not?

Add a pair of parentheses and they're exactly the same.

*((a) + 3) == a[3]

If one pair is needed, two pairs are better yet :

*((a) + 3) == (a)[3]

And because of precedence and associativity, a third one is needed :

*((a) + 3)[2] not the same as (a)[3][2] !

(*((a) + 3)) as close as can be to ((a)[3]) ;-)

Chqrlie.
 
C

Christian Bau

KKramsch said:
How close to equivalent are the expressions

a[3]

and

*(a + 3)

?

Can they be used entirely interchangeably, or are there situations
in which one will be OK and the other one not?


#define ARRAY1(a) a[3]
#define ARRAY2(a) *(a + 3)

static int ARRAY1 (x);
static int ARRAY2 (y);
 
G

Gordon Burditt

How close to equivalent are the expressions
a[3]
and
*(a + 3)
?

Can they be used entirely interchangeably, or are there situations
in which one will be OK and the other one not?

You can have problems if a is a macro. You may be able
to fix this with parentheses. Assuming a is a valid expression,

(a)[3]
and *((a)+3)
and *(3+(a))
and 3[(a)]

are equivalent. If a is defined as:
#define a ((
none of the above will compile at all.

Gordon L. Burditt
 
S

Stuart Gerchick

KKramsch said:
How close to equivalent are the expressions

a[3]

and

*(a + 3)

?

Can they be used entirely interchangeably, or are there situations
in which one will be OK and the other one not?

Thanks!

Karl


Assuming A is not a macro, they should be exactly the same. In addition

3[a] is also the same.
 
M

Marcus Lessard

Stuart Gerchick wrote:
Assuming A is not a macro, they should be exactly the same. In addition

3[a] is also the same.

Huh?? I understand that a[3] is the same as *(a + 3) but don't see how the
above is true. Is it that the compiler normally "imagines" an array as
being x[y] where x is a variable and y is a number and when you interchange
them it "knows" that you are describing the array as y[x]?
 
D

dandelion

Marcus Lessard said:
Stuart said:
Assuming A is not a macro, they should be exactly the same. In addition

3[a] is also the same.

Huh?? I understand that a[3] is the same as *(a + 3) but don't see how the
above is true. Is it that the compiler normally "imagines" an array as
being x[y] where x is a variable and y is a number and when you interchange
them it "knows" that you are describing the array as y[x]?

See FAQ (6.3 IIRC) . The first time i saw it I reacted pretty much the same.
Still, it's true.
 
J

Jens.Toerring

Marcus Lessard said:
Stuart said:
Assuming A is not a macro, they should be exactly the same. In addition

3[a] is also the same.

Huh?? I understand that a[3] is the same as *(a + 3) but don't see how the
above is true. Is it that the compiler normally "imagines" an array as
being x[y] where x is a variable and y is a number and when you interchange
them it "knows" that you are describing the array as y[x]?

That's because the compiler converts x[y] into *(x + y) before evalu-
ating it and x + y is commutative, so

a[ 3 ] == *( a + 3 ) == *( 3 + a ) == 3[ a ]

Regards, Jens
 
K

Keith Thompson

Marcus Lessard said:
Stuart said:
Assuming A is not a macro, they should be exactly the same. In addition

3[a] is also the same.

Huh?? I understand that a[3] is the same as *(a + 3) but don't see how the
above is true. Is it that the compiler normally "imagines" an array as
being x[y] where x is a variable and y is a number and when you interchange
them it "knows" that you are describing the array as y[x]?

That's because the compiler converts x[y] into *(x + y) before evalu-
ating it and x + y is commutative, so

a[ 3 ] == *( a + 3 ) == *( 3 + a ) == 3[ a ]

Right. It's unsurprising that addition of two numeric operands is
commutative, but it's not entirely obvious (at least to me) that
pointer+integer is equivalent to integer+pointer. The language
*could* have been defined so that pointer addition has to be
pointer+integer, with integer+pointer being illegal. This would have
made 3[a] illegal, which would have been no great loss IMHO.

If you think of it in terms of a hypothetical C-like language with
operator overloading, we have both
some_pointer_type "+"(some_pointer_type p, some_integer_type i);
and
some_pointer_type "+"(some_integer_type i, some_pointer_type p);
when we really only need the first.

But the C language is what it is, and the commutativity of addition
isn't going to change.
 
J

Jens.Toerring

Keith Thompson said:
Marcus Lessard said:
Stuart Gerchick wrote:

Assuming A is not a macro, they should be exactly the same. In addition

3[a] is also the same.

Huh?? I understand that a[3] is the same as *(a + 3) but don't see how the
above is true. Is it that the compiler normally "imagines" an array as
being x[y] where x is a variable and y is a number and when you interchange
them it "knows" that you are describing the array as y[x]?

That's because the compiler converts x[y] into *(x + y) before evalu-
ating it and x + y is commutative, so

a[ 3 ] == *( a + 3 ) == *( 3 + a ) == 3[ a ]
Right. It's unsurprising that addition of two numeric operands is
commutative, but it's not entirely obvious (at least to me) that
pointer+integer is equivalent to integer+pointer. The language
*could* have been defined so that pointer addition has to be
pointer+integer, with integer+pointer being illegal.

But that would make rules for other calculations involving pointers
and integers quite a bit more hairy to learn - I sometimes find my-
self having to subtract two pointers and adding integers, e.g. in
order to figure out a certain offset into an array, and then you
would have to take care to write

end_prt - mid_ptr - j + i

or at least

( end_ptr - j ) - ( mid_ptr - i )

but probably not

end_ptr - j - mid_ptr + i

since the compiler would be entitled to evaluate "j - mid_ptr"
first. Or it would make the rules for writing the compiler more
difficult, requiring the introduction of some kind of first and
second class types of addition and subtraction operators. I don't
think that it would be worth the additional troubles.
This would have
made 3[a] illegal, which would have been no great loss IMHO.

Well, of course modulo the fun you can have with pointing out
what weird things can be done (like '3[ "string" ]';-)

Regards, Jens
 
A

Arthur J. O'Dwyer

But that would make rules for other calculations involving pointers
and integers quite a bit more hairy to learn - I sometimes find my-
self having to subtract two pointers and adding integers, e.g. in
order to figure out a certain offset into an array, and then you
would have to take care to write

end_ptr - mid_ptr - j + i

or at least

( end_ptr - j ) - ( mid_ptr - i )

but probably not

end_ptr - j - mid_ptr + i

since the compiler would be entitled to evaluate "j - mid_ptr"
first.

No, it wouldn't. The optimizer is allowed to do whatever it likes,
but it always has to obey the basic parsing rules of the language.
Precedence says the above expression is invariably parsed as

(((end_ptr - j) - mid_ptr) + i)

---that is, (((ptr-int)-ptr)+int) ==> ((ptr-ptr)+int) ==> (int+int)
==> int.


[Drifting OT...]
Or it would make the rules for writing the compiler more
difficult, requiring the introduction of some kind of first and
second class types of addition and subtraction operators. I don't
think that it would be worth the additional troubles.

Again, it wouldn't, really. In fact, unless the compiler was written
using some clever compiler-compiler tricks[1], it would become slightly
easier to write; you could remove one line from the part of the
type-checker that looks something like

if (isPointer(lhs_type) && isInteger(rhs_type)) yield(PTR);
else if (isInteger(lhs_type) && isPointer(rhs_type)) yield(PTR);
else if (isInteger(lhs_type) && isInteger(rhs_type)) yield(INT);
else fail();

However, I will point out that I'm taking a university course on
compiler design right now, and we're translating a language that has
pointers and integers and allows a limited form pointer arithmetic.
In "L3", you can write the equivalent of

q = p+i; q = p-i;

but you cannot write the equivalent of

i = p-q; q = i+p;

and I find it quite annoying. So IMNSHO, the commutativity of addition
is a very important feature of any programming language, regardless of
whatever trouble it may cause for the implementor.

Interesting side note: I'm reading the Metafontbook right now, and
IIRC, when Knuth wrote Metafont, he explicitly coded in a "canonical
order" for additions such that real-number addition in Metafont is always
perfectly commutative and associative, no matter the magnitudes of the
operands. I think that's a nice idea.

-Arthur

[1] - I could imagine a very-high-level compiler generator that would
let the implementor specify things like

commutative left-associative operator + does (blah blah blah)
left-associative operator - does (blah blah blah)
commutative left-associative operator * does (blah blah blah)
[...]

and it might be more of a pain in such a language to specify what happens
when you're dealing with non-commutative operators. Unfortunately, I
don't know of any such compiler generator language in the real world. :(
 
K

Keith Thompson

Arthur J. O'Dwyer said:
However, I will point out that I'm taking a university course on
compiler design right now, and we're translating a language that has
pointers and integers and allows a limited form pointer arithmetic.
In "L3", you can write the equivalent of

q = p+i; q = p-i;

but you cannot write the equivalent of

i = p-q; q = i+p;

and I find it quite annoying. So IMNSHO, the commutativity of addition
is a very important feature of any programming language, regardless of
whatever trouble it may cause for the implementor.

(Presumably q and p are pointers, and i is an integer.)

I can see that the lack of "i = p-q" would be annoying, but why would
a user of the language have a problem with the lack of "q = i+p",
which can easily be replaced with "q = p+i"?
 
O

Old Wolf

Christian Bau said:
KKramsch said:
How close to equivalent are the expressions
a[3]
and
*(a + 3)
?

Can they be used entirely interchangeably, or are there situations
in which one will be OK and the other one not?

#define ARRAY1(a) a[3]
#define ARRAY2(a) *(a + 3)

static int ARRAY1 (x);
static int ARRAY2 (y);

In your example, a[3] etc. are not expressions.
 
P

Peter Shaggy Haywood

Groovy hepcat KKramsch was jivin' on Thu, 18 Nov 2004 13:59:50 +0000
(UTC) in comp.lang.c.
a said:
How close to equivalent are the expressions

a[3]

and

*(a + 3)

Can they be used entirely interchangeably,

No.
or are there situations
in which one will be OK and the other one not?

Yes. Try the following code:

#include <stdio.h>
#include <string.h>

void f(void)
{
#ifndef FOO
int a[3];
#else
int *(a + 3);
#endif

/* Do something to the array. */
strcpy(a, "ab");
puts(a);
}

int main(void)
{
f();
return 0;
}

Compile this program. Does it compile? Next, put the directive
"#define FOO" at the top of the code. Now, try compiling again. What
happens? Does it compile this time?

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,155
Messages
2,570,871
Members
47,401
Latest member
CliffGrime

Latest Threads

Top