Theory question on C and array passing
C is purely pass by value, though some say it is pass by reference when it comes to passing arrays. But not really, correct?
Since pointers are pass by value, i.e fun(int * p) receives a copy of the caller's pointer (pointing to the same location as the caller's pointer), then when an array decays into a pointer, the pointer passed into the function is also a copy (like any other pointer that is passed). The only magic is the array notation decaying into a pointer behind the scenes.
Right?
Thanks.
Yes, arrays are just pointers behind the scenes. So when passing an array by value, you're really just passing the pointer by value, which means the array-data itself is not copied.
Quote:Original post by Hodgman
Yes, arrays are just pointers behind the scenes. So when passing an array by value, you're really just passing the pointer by value, which means the array-data itself is not copied.
And the pointer to the elements of the array received from the caller is a normal pointer (that can be legally assigned to), i.e. not a second class array-type "pointer" that cannot be assigned to, correct? And this pointer can be made to point anywhere like any other pointer, not just to the first element of the array?
[Edited by - Ned_K on February 28, 2008 11:47:33 PM]
Yep.
For example, you could write a function to sum an array like this:
For example, you could write a function to sum an array like this:
int sum_array( int* array, int array_len ){ int sum = 0; while( array_len-- ) { sum += *array++; } return sum;}
Quote:Original post by Hodgman
Yes, arrays are just pointers behind the scenes.
This is not entirely correct: at the implementation level, arrays will behave slightly differently from pointers. Accessing a when a is an array addsi to the address of a and dereferences, whereas p when p is a pointer will dereference the address of p, adds i to that value, and dereferences again.
Quote:whereas p when p is a pointer will dereference the address of p, adds i to that value, and dereferences again.
Sorry, this is not correct. a is nothing more than syntactic sugar for *(a + i). C requires that for this to make sense, one of those things be a pointer and the other an integer value. That's it.
Note that *(a + i) is symmetrical, meaning that you can do strange things like this:
char str[] = "foo";printf("%c %c %c", 0[str], 1[str], 2[str]);
Which would be impossible if what you were saying was correct.
Quote:Original post by ToohrVykQuote:Original post by Hodgman
Yes, arrays are just pointers behind the scenes.
This is not entirely correct: at the implementation level, arrays will behave slightly differently from pointers. Accessing a when a is an array addsi to the address of a and dereferences, whereas p when p is a pointer will dereference the address of p, adds i to that value, and dereferences again.
lolwut?
You're saying that p is *((*p) + i). It's *(p + i).
I suppose you mean that the compiler knows that a will always be in the same place, while p will not, so it can skip the actual addition in the array's case but not in the pointer's case?
Quote:Original post by gsg
Sorry, this is not correct.
#include "discussion.hpp"
Quote:a is nothing more than syntactic sugar for *(a + i). C requires that for this to make sense, one of those things be a pointer and the other an integer value. That's it.
The existence of array decay completely obviates your argument: since arrays automatically become pointers when used in a pointer context, any pointer-only construct you exhibit (including *(a+i)) has no bearing on the actual nature of arrays, merely on their ability to become pointers on demand.
Quote:Original post by exwonder
You're saying that p is *((*p) + i). It's *(p + i).
Nope, this is not what I'm saying. My post stated that I was discussing the implementation level of the language, and p is not implemented as either *((*p) + i) or *(p + i), because it would make absolutely no sense for a C compiler to generate C code.
p is usually implemented as:
mov eax, DWORD PTR _i$[esp-4] mov ecx, DWORD PTR _p$[esp-4] mov eax, DWORD PTR [ecx+eax*4] ret 0
Whereas a is usually implemented as:
mov eax, DWORD PTR _i$[esp-4] mov eax, DWORD PTR _a$[esp+eax*4] ret 0
Notice the extra dereference in the first case.
Quote:Original post by ToohrVyk
Nope, this is not what I'm saying.
Yes I realized that you were correct between posts, but your terminology was poorly chosen. "Dereference" when talking about pointers in C implies something quite different than what you meant to the casual reader.
I guess I'd restate what you're saying as "accessing a pointer by index creates one additional add instruction and one additional load from memory when compared to array indexing", but the assembly you pasted clears it up as well.
Edit: "And possibly one extra multiply depending on the type of your pointer."
[Edited by - exwonder on February 29, 2008 4:07:46 AM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement