3

According to this

pointer is not stored as part of the array itself (or anywhere else in memory) when an array decays to pointer.

If the above statement is true,how can the data type of &array be different than array or &array[0] but all three have the same value in the following declaration.

int array[10];

I thought when the compiler silently decays an array to pointer, it should give the pointer some memory address. if it's not, then where does the pointer get stored?

Thanks in advance.

Community
  • 1
  • 1
user1585554
  • 43
  • 1
  • 5

4 Answers4

4

I don't see where you get the idea that the pointer has to be stored somewhere. For what purpose? There's no C++ code that would require that pointer to be stored anywhere.

When an abstract C++ machine evaluates something like

int a = 2, b = 3, c = 4;
int i = (a + b) * c;

the inner subexpression a + b evaluates to 5. However, that 5 is not really stored anywhere from the language point of view. It is just a temporary value of 5 that exists for a fleeting moment only to be multiplied by c and forgotten forever. Such immaterial expression results in C++ are called rvalues. It is generally unspecified where rvalues live. During the evaluation of the above expression, the value of 5 might appear for a moment in some CPU register. Or it might even be temporarily stored in some unnamed memory area, if the compiler decided to do so, but this is not something you can see at the level of C++ code.

The same is true for the pointer resulting from array-to-pointer conversion. That pointer is juts an rvalue - a temporary value that doesn't live anywhere in memory. It simply doesn't need to live anywhere in memory.

It is not clear what you are trying to express by your &array reference. Expression &array does not involve array-to-pointer conversion, which means that it has no relation to the issue in question at all.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Thanks. by using **&array**, I meant that it has the same value as **&array[0]** or **array** but referring to a contiguous memory block, how can the compiler resolve that? is it possible that two different data-types share the same memory address? – user1585554 Aug 08 '12 at 19:25
  • "is it possible that two different data-types share the same memory address?" Of course it's possible. In fact, one of C's language features gives you an explicit way to indicate that. http://publications.gbdirect.co.uk/c_book/chapter6/unions.html – JAB Aug 09 '12 at 11:37
3

when you use address-of operator on expression array, expression array doesn't decays in to pointer (same when you use sizeof, when you use typeid, and when you pass an array as an argument where the formal argument is a reference to array). In other expressions it generally decays to pointer to its first element.

given the declaration

    int array[10];

the type of &array is int (*const)[10] where as type of &array[0] is int *const == type of array in an expression where it decays.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
Mr.Anubis
  • 5,132
  • 6
  • 29
  • 44
  • Thanks, but if you agree on the statement, it says that pointer is not part of array nor stored anywhere else in memory, so where is the pointer stores when it decays to pointer? – user1585554 Aug 08 '12 at 19:01
  • If I'm not mistaken, it's stored in a register (or the equivalent) of the processor the program is being run on if you aren't doing anything more with the decayed pointer aside from referencing it in a statement, and then ignored from then on. When you pass it into a function or assign it to something, however, it does indeed store that decayed pointer somewhere in memory (or possibly not, depending on what optimizations are active and how the pointer is used). Or something like that. – JAB Aug 08 '12 at 19:09
  • @user1585554 decayed pointer is stored in memory until the expression last – Mr.Anubis Aug 08 '12 at 19:19
  • Data types don't have addresses, their object's have. yes they can have same address. are you still confused by something? – Mr.Anubis Aug 08 '12 at 19:32
  • @ Mr.Anubis Sorry, I meant that their identifiers or objects you mentioned, can they have the same address e.g. **&array** and **&array[0]** and different types? – user1585554 Aug 08 '12 at 19:37
  • I think I got the idea from rvalue expressions, but aren't the addresses of &array and &array[0] the same? – user1585554 Aug 08 '12 at 19:46
  • @user1585554 object `array` which is array of 10 `int`s overlaps objects array[0]...array[9] in memory, that's how arrays are laid in memory in row major order. That's why you see same address, understood? – Mr.Anubis Aug 08 '12 at 19:50
2

This is part of expression evaluation. When the compiler evaluates any expression, such as 3+4, (unsigned int) 3, or &array[3] or simply array, it manages all the temporary values that occur in a variety of ways, often by performing whatever calculations are necessary in processor registers. When you use an array name as a pointer, the compiler typically produces instructions to load the address of the array into a register and then performs whatever other arithmetic you have specified to do with the pointer.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
1

As you can tell from http://ideone.com/Qw1aA, &array, array, and &array[0] all represent the same value: the memory address of the first element in the array.

However, just because two values are the same doesn't mean they represent the same things; in this case, it's a semantic difference (which can still be important, as, for example, with a regular array you can use sizeof() to find its length (in bytes) in C, while you can't do so if you pass the array in place of a pointer argument).

Also, even if a function has an array type in its arguments, the results won't be the same inside the function when passing in an array as shown in http://ideone.com/jAeAn, because of the pointer decomposition, as shown in the error message here: http://ideone.com/yn0zc.

JAB
  • 20,783
  • 6
  • 71
  • 80
  • `&array` actually has a different *type* (pointer to array of 10 `int`s) than the other two (pointer to `int`), even though the *values*, when converted to `void *` or any integer type, will all be the same. For example, if `sizeof (int) == 4`, then `&array + 1` will point 40 bytes past the start of `array`, while both `array + 1` and `&array[0] + 1` will point 4 bytes past the start. – j_random_hacker Aug 08 '12 at 18:58
  • Perhaps I used "semantic" wrongly. That's what I meant; even though the values are the same, the way the compiler handles the values is different, like how the literals `0` and `0f` are represented by the same bits, and themselves represent the same value, but are also different types. – JAB Aug 08 '12 at 19:07