Address of array behavior in pointer arithmetic

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

  1. joshc

    joshc Guest

    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
    #1
    1. Advertising

  2. joshc

    pete Guest

    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
    #2
    1. Advertising

  3. joshc

    jackdorse Guest

    > 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
    #3
  4. joshc

    deepak Guest

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

    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
    #4
  5. deepak wrote:
    > As said,
    > val = arr. But if gives array name, it 'll generate the starting
    > address of array.
    >
    > 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
    #5
  6. joshc

    Chris Dollin Guest

    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.
    Chris Dollin, Jun 15, 2006
    #6
  7. "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.

    Please read section 6 of the comp.lang.c FAQ <http://www.c-faq.com/>.

    (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
    #7
  8. joshc

    jackdorse Guest

    Nils O. Selåsdal wrote:

    > deepak wrote:
    > > As said,
    > > val = arr. But if gives array name, it 'll generate the starting
    > > address of array.
    > >
    > > 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
    #8
  9. joshc

    jackdorse Guest

    Nils O. Selåsdal wrote:

    > deepak wrote:
    > > As said,
    > > val = arr. But if gives array name, it 'll generate the starting
    > > address of array.
    > >
    > > 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
    #9
  10. joshc

    deepak Guest

    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
    #10
  11. joshc

    joshc Guest

    Keith Thompson wrote:

    <snip>

    > That's wrong. &arr is the address of the array; there's no
    > pointer-to-pointer anywhere.
    >
    > Please read section 6 of the comp.lang.c FAQ <http://www.c-faq.com/>.
    >
    > (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
    #11
  12. joshc

    joshc Guest

    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
    #12
  13. joshc

    pete Guest

    "Nils O. Selåsdal" wrote:
    >
    > deepak wrote:
    > > As said,
    > > val = arr. But if gives array name, it 'll generate the starting
    > > address of array.
    > >
    > > 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
    #13
  14. joshc

    pete Guest

    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
    #14
  15. joshc

    Chris Torek Guest

    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
    pointer that points to the entire array. See also:

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

    for a graphical depiction of what a "pointer to an entire array"
    means. Had you added 1 instead of 0, the "big circle" would move
    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
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
    Chris Torek, Jun 15, 2006
    #15
  16. "joshc" <> writes:
    > Keith Thompson wrote:
    >
    > <snip>
    >
    >> That's wrong. &arr is the address of the array; there's no
    >> pointer-to-pointer anywhere.
    >>
    >> Please read section 6 of the comp.lang.c FAQ <http://www.c-faq.com/>.
    >>
    >> (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
    #16
  17. joshc

    Joe Wright Guest

    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
    #17
    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. Mike H

    3D array pointer arithmetic

    Mike H, Dec 21, 2004, in forum: C Programming
    Replies:
    9
    Views:
    677
    John Smith
    Dec 22, 2004
  2. joshc
    Replies:
    5
    Views:
    556
    Keith Thompson
    Mar 31, 2005
  3. jimjim
    Replies:
    16
    Views:
    839
    Jordan Abel
    Mar 28, 2006
  4. vjay

    Array address arithmetic

    vjay, Dec 9, 2007, in forum: C Programming
    Replies:
    15
    Views:
    565
    Keith Thompson
    Dec 11, 2007
  5. Stanley Rice

    Address of array && address of pointer to array

    Stanley Rice, Sep 14, 2011, in forum: C Programming
    Replies:
    33
    Views:
    1,142
    Keith Thompson
    Sep 20, 2011
Loading...

Share This Page