Are C arrays passed by reference?

Started by
43 comments, last by MadKeithV 15 years, 8 months ago
I agree that an array is not a pointer, but what pointer arithmetic is disallowed?
int a[] = { 1, 2, 3 };int b;int i = 1;b = a; //worksb = i[a]; //worksb = *(i + a); //worksb = *(a + i); //worksb = *a; // works
Advertisement
MY apologies, the statement sounds a little too broad. I was referring to my example earlier. Examples of pointer arithmetic that pointers can do but arrays cannot are +=, -=, ++ and --. Its a minor point, if you pretend arrays are const pointers, but its still an important difference.

Another is that the address of an array and the first element in the array are the same, whereas a pointer has a distinct address.
Quote:Original post by TheTroll
Read 6.3.

"A reference to an object of type array-of-T which appears in an expression decays (with three exceptions) into a pointer to its first element; the type of the resultant pointer is pointer-to-T. "

theTroll


The key phrase in that quote is "decays to". "Array" is a distinct type in C++, and most importantly is not a pointer. Arrays however are implicitly convertible to a pointer to their first element. This is the same reason why an int is not a double. The langauge simply provides an implicit int->double conversion.

Also I'd like to make another nitpick: arrays are not passed by reference. The reason is that this is how you pass an array by reference:

// Passing an array by referencevoid myFun(char (&myArray)[255]){    std::cout << sizeof(myArray) << std::endl; // This will output 255 bytes}


Also, they're not passed as a pointer either, because this is how you pass them as a pointer:

// Passing an array by pointervoid myFun(char (*myArray)[255]){    std::cout << sizeof(myArray) << std::endl; // This will be four bytes, aka the size of a pointer}


In C++ we cant make willy nilly use of the phrase "pass by reference" as it means something distinct. However raising that point might cause a student undue confusion.
In C++ you can declare a function like this.

int sum_arr(int arr[], int n)

and it would be the same as this

int sum_arr(int * arr, int n)

this is because in C++
int * arr and int arr[]
have the exact meaning but only when used in a function header or prototype.
Quote:Original post by rip-off
the address of an array and the first element in the array are the same

No, &a and &a[0] have distinct types.

For example, given int a[10];, &a yields a pointer to an array of 10 ints, whereas &a[0] yields a pointer to an int.

Quote:Original post by fpsgamer
In C++ we cant make willy nilly use of the phrase "pass by reference" as it means something distinct.

You are absolutely correct, but I never mentioned C++ :) If I had to teach a C++ class, I would start with vectors, not arrays.
Since there is no real pass by reference in C, I figured it couldn't hurt too much to say "arrays appear to be passed by reference".

Quote:Original post by mattnenterprise
this is because in C++
int * arr and int arr[]
have the exact meaning but only when used in a function header or prototype.

Correct, but why do you emphasize C++? C has the exact same (non-recursive) specifications regarding T[] and T* for function parameters.
Quote:Original post by DevFred
Quote:Original post by rip-off
the address of an array and the first element in the array are the same

No, &a and &a[0] have distinct types.


I know [smile].

I didn't mention types, I am talking about if you were to print their values.

The point was supposed to be that if an array is a pointer, and its address is the same as the first element in the array, then the pointer value would vary when you changed the value of the first element, which is obviously a nonsensical situation.
Quote:Original post by DevFred
Quote:Original post by fpsgamer
In C++ we cant make willy nilly use of the phrase "pass by reference" as it means something distinct.

You are absolutely correct, but I never mentioned C++ :) If I had to teach a C++ class, I would start with vectors, not arrays.
Since there is no real pass by reference in C, I figured it couldn't hurt too much to say "arrays appear to be passed by reference".


Thanks for correcting me :) I am clearly the one who forgot what language we are talking about.
Personally, I wish more classes taught about pointers early. It's a concept that many students have trouble with, yet is so fundamental that I've never understood why it gets put off until later.

Certainly, there's many basic concepts that should be taught before pointers, but I for one think that arrays aren't one of them. Teach arrays AFTER pointers, then you can more clearly describe how arrays differ. I've never liked it when I enter a new class, and am told that something is "like this... but not really", and then later being told that "actually... this is how it REALLY works".

[Edited by - gharen2 on July 28, 2008 1:29:48 AM]
Post edited for code errors. Copy & Pasted for 9001% more accuracy.

Quote:Original post by fpsgamer
Quote:Original post by TheTroll
Read 6.3.

"A reference to an object of type array-of-T which appears in an expression decays (with three exceptions) into a pointer to its first element; the type of the resultant pointer is pointer-to-T. "

theTroll


The key phrase in that quote is "decays to".


Indeed (emphasis added in the original quote). Decays does not mean "is", it means "is implicitly convertable to". This can be an important distinction -- for example, trying to cast a pointer to an array of int:
int array[3];int (*ptr_to_array)[3] = &array

into a pointer to a pointer to an int:
int ** ptr_to_ptr = (int**)ptr_to_array;// Note that the above won't compile without the explicit cast.

And then using that pointer yields undefined behavior. And no, I'm not talking "in theory", I'm talking about in practice almost certainly having a crash at best:
// Compiled with MSVC2008 and executed on a typical x86 box:array[0]           = 42; // This works fine, defined behavior(*ptr_to_array)[0] = 42; // This works fine, defined behavior(*ptr_to_ptr)[0]   = 42; // This generates an Access violation writing location 0x0000002a (42)                         // (it tried to treat the integer value stored at array[0] as an address)                         // (Yes, this statement invoked undefined behavior)


[Edited by - MaulingMonkey on July 28, 2008 3:54:54 AM]
Quote:Original post by gharen2
Personally, I wish more classes taught about pointers early.

The problem is: IMHO there are no simple examples where pointers make sense (without arrays and dynamic allocation), except for emulating pass by reference (by passing pointers by value). Maybe you have a good example?

I have seen way too many introductions to pointers using code like this:
int i = 3;int *p = &i*p = 5;assert i == 5;

And almost everyone immediately asks themselves "Why the hell would I want to do that? Why not just i = 5; ?". Poor examples like these are the reason for countless "What's the use of pointers?" threads on gamedev.

I think I am going to introduce pointers as a means to implement a swap function, although I am not completely satisfied with that.

This topic is closed to new replies.

Advertisement