Quote:Original post by paulecoyote
Yeah, before first coffee, so some of what you said is true about the new thing. Few typos, getting distracted then doing this, blah blah blah.
However *& is valid in C++. Though reading through your post I think you did say that, you just picked up on the &* typo.
Yes, I know references to pointers are valid, I never said they weren't. I was just pointing out that the example you gave was actually a pointer to a reference, which is not valid.
Quote:Original post by paulecoyote
anyway... the (&char)[x][y] thing for a parameter definition threw me, because
& = address operator
... but arrays are implicitly sent by reference anyway... so u r sending a reference to a reference. Which isn't the case because otherwise the below snippet would be disproved.
Not exactly. The standard allows parameters using [] or [some_value] as syntactic fluff, which actually mean the same thing as a pointer to the element type, which is not a pointer to the array. Using that syntax does not pass the array by reference, but rather, it passes the first element by pointer, which only gives you some similar syntactic use (and gets rid of the array type information).
My example does not in any way mean a reference to a reference or a reference to a pointer. You are confused due to the misconception that an array is a pointer, which is an all too common mistake. Array types are completely separate from pointer types, and different size arrays are different types as well. They are not pointer nor reference types, but rather they are types which represent exactly what an array is -- a contiguous block of a certain number of items of a given type.
your_type (&your_array_reference)[your_array_size] = some_array
In that example, "your_array_reference" is a reference to "some_array" whose elements are of type "your_type" and whose size is "your_array_size." It's not a reference to a pointer, it's a reference to the array and can be used in every way just as though you were working with "some_array." Again, there are no extra gotchas. It's a reference just like a reference to any other type, only here it's to an array.
That is all that my example does -- it makes the function take a reference to the array instead of a pointer to the first element. This keeps the array being referenced as it should -- an actual array of a specific size, not just utilizing a pointer to the first element to provide some similar syntax, and it also disallows passing arrays of different sizes, etc. This leaves less room for error since passing an array of a different size will give an error at compile time (as opposed to possibly getting an access violation at runtime), and since it is a reference and not a pointer, it disallows the passing of an uninitialized pointer or a null pointer, unlike if you were using a pointer.
Quote:Original post by paulecoyote
(Web Quote - though Deitel & Deitel supports)
http://www.fredosaurus.com/notes-cpp/arrayptr/arraysaspointers2.html
& operator applied to arrays does nothing.
The & (address of) operator normally returns the address of the operand. However, arrays are the exception. When applied to an array (which is an address), it has the same value as the array reference without the operator. This isn't true of the equivalent pointers, which have an independent address. The example below show this. When cout is given an address, it prints it in hexadecimal (except addresses of characters, which are assumed to be the beginning of a c-string). For example,
*** Source Snippet Removed ***
Unfortunately, this is why people never learn properly -- the sources they learn from are incorrect. I can't fully express how angry that link made me, since it provides incorrect information to people learning the language! An array is in no way a pointer, as I have stated. There is absolutely no exception to using the address of operator on an array -- it gives you a pointer to the array type. For instance:
int array[10];int (*pointer)[10] = &array
&array gives you the address of the array, which is of the type int (*)[10].
This is because an array is not a pointer. It is its own entity that is capable of implicitly yielding a pointer to its first element. This is done so that you don't have to type &array[0] every time you need a pointer to the first element (such as for passing a pointer to the first element to a function). Again, this in no way makes array a pointer, it's just a way to implicitly perform an operation that you'd otherwise have to explicitly write out. When you make an array, no pointer is created -- all that happens is a chunk of contiguous memory is created for the elements. Using the array name where a pointer to the element type is expected will just automatically take the address of the first element.
Quote:Original post by paulecoyote
This produces the following output showing the unexpected equality a == &a. The value of p is the same as a as expected, and &p is the address of the memory location of the p variable as expected.
This is true for the same reason that the address of the first element of a structure is the same value as the address of the structure itself. This in no way means that the first element of the structure and the element as a whole are the same thing. They are two completely different entities who just share the same starting location in memory. While the value of the address of the first element of "a" and the value of the address of "a" itself are the same, they are completely different types and mean completely different things! For instance:
int array[10];int* this_will_work = array; // Implicitly yields the address of the first element, okayint* this_will_not_work = &array // ERROR because &array's type is actually int (*)[10]
This correctly will give you error because &array is not the same as &array[0]. The former is a pointer to the array type while the latter is a pointer to the element type.
You can also see this by outputting typeid( &array ).name() and comparing it to typeid( array ).name() as well as typeid( &array[0] ).name(). All three should give you different types.
Edit in response to your edit:Quote:Original post by paulecoyote
EDIT 2:
So... & & is illegal, &* is illegal, but *& is not. All arrays are implicitly pointers to the first element (as above snippet proves - a == p). By putting & in (char&)[][] it's like a &* which is illegal. But the compiler lets u get away with it and just thinks well... you actually did just mean the array reference... not an array reference reference.
char (&your_reference)[some_size][some_other_size]
in no way means &*. You are again just confused because you think that an array is a pointer which is completely untrue. The compiler isn't "letting you get away with it." It works because it literally means a reference to the array -- not a pointer to a reference or anything of the sort. There is nothing invalid about it! An array is an array is an array is an array. It is not, however, a pointer.
Quote:Original post by paulecoyote
The other way of interpreting it is that it's a *&, but that's ignored because compiler doesn't think you really mean to send across a reference to an array - as all arrays are passed that way anyway. Hence why a == &a. Still doesn't explain the r-value thing though when used as parameter.
It means neither of the two things you are describing. Again, you are just not understanding that arrays are their own types and are in no way pointer types. Passing an array like that means you are passing the entire array by reference. The way you were doing it, on the otherhand, actually passes the first element of the array by pointer, which is completely different. You are just confused by the syntactic similarities in usage between arrays and pointers.
[Edited by - Polymorphic OOP on December 2, 2004 7:23:47 AM]