445,804 Members | 1,627 Online
Need help? Post your question and get tips & solutions from a community of 445,804 IT Pros & Developers. It's quick & easy.

# Address of array behavior in pointer arithmetic

 P: n/a 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. Jun 15 '06 #1
16 Replies

 P: n/a 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 Jun 15 '06 #2

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

 P: n/a 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. Jun 15 '06 #4

 P: n/a 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: Jun 15 '06 #5

 P: n/a 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. Jun 15 '06 #6

 P: n/a "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 . (And please don't use silly abbreviations like "u".) -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <*> We must do something. This is something. Therefore, we must do this. Jun 15 '06 #7

 P: n/a 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 Jun 15 '06 #8

 P: n/a 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 Jun 15 '06 #9

 P: n/a 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. Jun 15 '06 #10

 P: n/a Keith Thompson wrote: 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 . (And please don't use silly abbreviations like "u".) -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <*> 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. Jun 15 '06 #11

 P: n/a 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. Jun 15 '06 #12

 P: n/a "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 Jun 15 '06 #13

 P: n/a 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 Jun 15 '06 #14

 P: n/a In article <11**********************@y41g2000cwy.googlegroups .com> 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 arrwhich is a pointer to int when used in value context. Correct. Can someone explain what really happens in the code snippetabove? In other words what the (&arr + 0) expression evaluates to interms 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. Jun 15 '06 #15

 P: n/a "joshc" writes: Keith Thompson wrote: 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 . (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) ks***@mib.org San Diego Supercomputer Center <*> We must do something. This is something. Therefore, we must do this. Jun 15 '06 #16

 P: n/a 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 --- Jun 15 '06 #17

### This discussion thread is closed

Replies have been disabled for this discussion.