# Address of array behavior in pointer arithmetic

Discussion in 'C Programming' started by joshc, Jun 15, 2006.

1. ### joshcGuest

So I've read the relevant sections in the FAQ and the other threads on
this topic but didn't find the exact answer to my question. A fellow
developer wrote the following in some code:

uint16 arr[10];

uint16 val;

val = *(&arr + 0);

So I know that &arr is a pointer to an array of 10 ints versus arr
which is a pointer to int when used in value context. In my case my
compiler ended up storing the address of 'arr' in 'val' for the code
above. Can someone explain what really happens in the code snippet
above? In other words what the (&arr + 0) expression evaluates to in
terms of type, etc.

Thanks.

joshc, Jun 15, 2006

2. ### peteGuest

joshc wrote:

> uint16 arr[10];
>
> uint16 val;
>
> val = *(&arr + 0);

> &arr is a pointer to an array of 10 ints

> In other words what the (&arr + 0) expression evaluates to in
> terms of type, etc.

(&arr + 0)
is the same as
&arr

val = *(&arr + 0);
is the same as
val = arr;
and should generate the same warning.

--
pete

pete, Jun 15, 2006

3. ### jackdorseGuest

> uint16 arr[10];
>
> uint16 val;
>
> val = *(&arr + 0);
>
> So I know that &arr is a pointer to an array of 10 ints versus arr
> which is a pointer to int when used in value context. In my case my
> compiler ended up storing the address of 'arr' in 'val' for the code
> above. Can someone explain what really happens in the code snippet
> above? In other words what the (&arr + 0) expression evaluates to in
> terms of type, etc.
>
> Thanks.

arr is a simple pointer of the array. when u say &arr it is something
similar to pointer to pointer.

so when u try to dereference (&arr + 0) it results into an address.
Also, if u look at the warning generated by gcc compiler

"warning: assignment makes integer from pointer without a cast"

makes the point very clear.

jackdorse, Jun 15, 2006
4. ### deepakGuest

As said,
val = arr. But if gives array name, it 'll generate the starting

This one 'll be correct.

main()
{

int val;
int arr[10];

val = **(&arr + 0);

}

Thanks,
Deepak.
jackdorse wrote:
> > uint16 arr[10];
> >
> > uint16 val;
> >
> > val = *(&arr + 0);
> >
> > So I know that &arr is a pointer to an array of 10 ints versus arr
> > which is a pointer to int when used in value context. In my case my
> > compiler ended up storing the address of 'arr' in 'val' for the code
> > above. Can someone explain what really happens in the code snippet
> > above? In other words what the (&arr + 0) expression evaluates to in
> > terms of type, etc.
> >
> > Thanks.

>
> arr is a simple pointer of the array. when u say &arr it is something
> similar to pointer to pointer.
>
> so when u try to dereference (&arr + 0) it results into an address.
> Also, if u look at the warning generated by gcc compiler
>
> "warning: assignment makes integer from pointer without a cast"
>
> makes the point very clear.

deepak, Jun 15, 2006
5. ### =?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=Guest

deepak wrote:
> As said,
> val = arr. But if gives array name, it 'll generate the starting
>
> This one 'll be correct.

Not really.
&arr isn't an int** , it is an int (*)[10].

> main()
> {
>
> int val;
> int arr[10];
>
> val = **(&arr + 0);
>
> }
>
> Thanks,
> Deepak.
> jackdorse wrote:

=?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=, Jun 15, 2006
6. ### Chris DollinGuest

joshc wrote:

> So I've read the relevant sections in the FAQ and the other threads on
> this topic but didn't find the exact answer to my question. A fellow
> developer wrote the following in some code:
>
> uint16 arr[10];
>
> uint16 val;
>
> val = *(&arr + 0);

was your fellow developer /thinking/ when they wrote that?

--
Chris "HOT NEWS: x + 0 = x" Dollin
A rock is not a fact. A rock is a rock.

Chris Dollin, Jun 15, 2006
7. ### Keith ThompsonGuest

"jackdorse" <> writes:
>> uint16 arr[10];
>>
>> uint16 val;
>>
>> val = *(&arr + 0);
>>
>> So I know that &arr is a pointer to an array of 10 ints versus arr
>> which is a pointer to int when used in value context. In my case my
>> compiler ended up storing the address of 'arr' in 'val' for the code
>> above. Can someone explain what really happens in the code snippet
>> above? In other words what the (&arr + 0) expression evaluates to in
>> terms of type, etc.
>>
>> Thanks.

>
> arr is a simple pointer of the array. when u say &arr it is something
> similar to pointer to pointer.

That's wrong. &arr is the address of the array; there's no
pointer-to-pointer anywhere.

(And please don't use silly abbreviations like "u".)

--
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, Jun 15, 2006
8. ### jackdorseGuest

Nils O. Selåsdal wrote:

> deepak wrote:
> > As said,
> > val = arr. But if gives array name, it 'll generate the starting
> >
> > This one 'll be correct.

> Not really.
> &arr isn't an int** , it is an int (*)[10].
>

agreed. srry for the mistake

jackdorse, Jun 15, 2006
9. ### jackdorseGuest

Nils O. Selåsdal wrote:

> deepak wrote:
> > As said,
> > val = arr. But if gives array name, it 'll generate the starting
> >
> > This one 'll be correct.

> Not really.
> &arr isn't an int** , it is an int (*)[10].
>

agreed. thanx for drawing my attention

jackdorse, Jun 15, 2006
10. ### deepakGuest

Nils,

Just want to know mistake was from me or Jachorse?

Chris Dollin wrote:
> joshc wrote:
>
> > So I've read the relevant sections in the FAQ and the other threads on
> > this topic but didn't find the exact answer to my question. A fellow
> > developer wrote the following in some code:
> >
> > uint16 arr[10];
> >
> > uint16 val;
> >
> > val = *(&arr + 0);

>
> Never mind the technical answer to your question: what on /Earth/
> was your fellow developer /thinking/ when they wrote that?
>
> --
> Chris "HOT NEWS: x + 0 = x" Dollin
> A rock is not a fact. A rock is a rock.

deepak, Jun 15, 2006
11. ### joshcGuest

Keith Thompson wrote:

<snip>

> That's wrong. &arr is the address of the array; there's no
> pointer-to-pointer anywhere.
>
>
> (And please don't use silly abbreviations like "u".)
>
> --
> 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.

If you read my post I said I read the FAQ but was asking for how that
expression ended up with the address of the array. The concept of
pointer to array of 10 ints seems very abstract to me. In actual terms
it would seem to point to the same address as 'arr' itself but has a
different type. Why that different type causes the result I mention is
what I want to know.

Regarding abbreviations like "u", are you referring to my use of
"uint16". If that's the case then those are types we've defined and it
isn't an abbreviation. It's definition is based on which implementation
we're using and that's why I didn't include the typedef.

Thanks.

joshc, Jun 15, 2006
12. ### joshcGuest

Chris Dollin wrote:
> joshc wrote:
>
> > So I've read the relevant sections in the FAQ and the other threads on
> > this topic but didn't find the exact answer to my question. A fellow
> > developer wrote the following in some code:
> >
> > uint16 arr[10];
> >
> > uint16 val;
> >
> > val = *(&arr + 0);

>
> Never mind the technical answer to your question: what on /Earth/
> was your fellow developer /thinking/ when they wrote that?
>
> --
> Chris "HOT NEWS: x + 0 = x" Dollin
> A rock is not a fact. A rock is a rock.

I guess he meant to say *(&arr[0] + 0) but for some reason or the other
thought &arr might result in the same. I'm sure a lot of people don't
know that that is incorrect. I myself have been programming in C for
quite some time and consider myself fairly proficient and althought
I've never used &arr I wasn't sure that it was wrong. I reviewed his
code and pointed out that that was probably the error and sure enough
it was. As far as adding 0 in the real code it is replaced by a
function parameter.

joshc, Jun 15, 2006
13. ### peteGuest

"Nils O. Selåsdal" wrote:
>
> deepak wrote:
> > As said,
> > val = arr. But if gives array name, it 'll generate the starting
> >
> > This one 'll be correct.

> Not really.
> &arr isn't an int** , it is an int (*)[10].

That doesn't matter.
The result of dereferencing (&arr) is an expression of array type,
which converts to an expression of pointer type.

There's nothing wrong with the code quoted below:

> > int val;
> > int arr[10];
> >
> > val = **(&arr + 0);

--
pete

pete, Jun 15, 2006
14. ### peteGuest

joshc wrote:
>
> Keith Thompson wrote:

> > (And please don't use silly abbreviations like "u".)

> Regarding abbreviations like "u", are you referring to my use of
> "uint16".

"when u say &arr it is something similar to ..."

--
pete

pete, Jun 15, 2006
15. ### Chris TorekGuest

In article <>
joshc <> wrote:
>[someone] wrote the following in some code:
>
>uint16 arr[10];
>uint16 val;
>
>val = *(&arr + 0);
>
>So I know that &arr is a pointer to an array of 10 ints versus arr
>which is a pointer to int when used in value context.

Correct.

>Can someone explain what really happens in the code snippet
>above? In other words what the (&arr + 0) expression evaluates to in
>terms of type, etc.

&arr produces a value of type "pointer to (array 10 of uint16)"
(presumably uint16 is a typedef-name for some actual C type, perhaps
"unsigned short"), pointing to the entire array "arr". Adding zero
to this value leaves the value unchanged, so you still have a

http://web.torek.net/torek/c/pa.html

for a graphical depiction of what a "pointer to an entire array"
forward by "one whole array", as shown on the page above.

In any case, after stepping forward by "zero whole arrays" -- so
that the pointer still points to the entire array -- this pointer
is fed to the unary "*" operator. The "*" operator follows the
pointer to the thing to which it points, namely, the entire array.
Since "the thing to which it points" is an array *object*, but this
is the right hand side of an "=" assignment, we need a value.
This array object thus runs into The Rule about arrays and pointers
in C. The expression's value is then the value found by computing
a pointer to the first element of the array, i.e., &arr[0].

Of course, this value is a pointer, not a "uint16", so the C compiler
gives you a complaint of some sort, and then probably generates
code that first wrecks the full (typically 32 or 64 bit) address,
and places some 16-bit wreckage into the "uint16" variable named
"val".
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
Reading email is like searching for food in the garbage, thanks to spammers.

Chris Torek, Jun 15, 2006
16. ### Keith ThompsonGuest

"joshc" <> writes:
> Keith Thompson wrote:
>
> <snip>
>
>> That's wrong. &arr is the address of the array; there's no
>> pointer-to-pointer anywhere.
>>
>>
>> (And please don't use silly abbreviations like "u".)

(And don't quote signatures unless you're commenting on them. Thanks.)

> If you read my post I said I read the FAQ but was asking for how that
> expression ended up with the address of the array. The concept of
> pointer to array of 10 ints seems very abstract to me. In actual terms
> it would seem to point to the same address as 'arr' itself but has a
> different type. Why that different type causes the result I mention is
> what I want to know.

The important thing to remember is that arrays are not pointers, and
pointers are not arrays. A pointer to an array of 10 ints is really
no more abstract than a pointer to any other type.

When you declare

uint16 arr[10];

you're declaring an array object. No pointer object is created
anywhere. The expression &arr is a pointer *value*; it points to the
array object. It's exactly the same as:

int x;

where &x evaluates to a pointer value, which points to the int object.

Pointers point to objects. If &arr were, as you suggest, a pointer to
pointer, there would have to be some pointer object for it to point
to. There isn't.

In most contexts, an expression of array type is implicitly converted
to a pointer to its first element. The exceptions to this rule are
the operand of a unary sizeof or "&" operator, or a string literal
used in an initializer for an array object.

[..]

> Regarding abbreviations like "u", are you referring to my use of
> "uint16".

No, I'm referring to the use of "u" for "you" (which I see you're not
using anymore; thank you).

--
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, Jun 15, 2006
17. ### Joe WrightGuest

joshc wrote:
> So I've read the relevant sections in the FAQ and the other threads on
> this topic but didn't find the exact answer to my question. A fellow
> developer wrote the following in some code:
>
> uint16 arr[10];
>
> uint16 val;
>
> val = *(&arr + 0);
>
> So I know that &arr is a pointer to an array of 10 ints versus arr
> which is a pointer to int when used in value context. In my case my
> compiler ended up storing the address of 'arr' in 'val' for the code
> above. Can someone explain what really happens in the code snippet
> above? In other words what the (&arr + 0) expression evaluates to in
> terms of type, etc.
>
> Thanks.
>

The dereference operator (*) and the address of operator (&) are
complementary and cancel each other out. *(&arr) == arr.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---

Joe Wright, Jun 15, 2006