Re: well-defined terminology versus generally accepted terminology regarding pointers and arrays
"Paul" <pchristor@yahoo.co.uk> wrote in message
news:wnssp.5183$9h6.5012@newsfe02.ams2...
<snip>
When I replied to this before I didn't have time to take a proper look at
it, but I found it interesting so I came back to give it a proper
examination.
struct Foo { operator int* (); };
That is a declaration and definition of a type Foo.
Foo foo;
That is a declaration and definition of an object foo. foo is not a
pointer.
int x = *foo;
That is an implicit conversion from an expression of type "Foo" to an
expression of type "int*", then a dereference of that pointer. Note
that I do not deference foo. Instead, an implicit conversion to
pointer happens, and afterwards a deference of that (temporary aka
rvalue) pointer happens.
Hmm ok well lets make some code that actually does what you are explaining
here:
struct Foo {
int x, y;
operator int*(){ return (int*)this; }
};
Ok I'll give Foo a couple of int members, so there is actually something to
reference when we access a foo object.
And I will give Foo::operator int*() some implemenation so it actually
works.
Now some code to confirm that foo objects behave as expected:
Foo foo;
std::cout<< "&foo:\t" << &foo << std::endl;
int* p = foo;
std::cout<< "p:\t" << p << std::endl;
So foo is implicitly converted to an int* when we assign it to p.
I'll assume you accept this confirms that foo converts to an int* in the
expected way.
Yes but I dont see tihs as the same because a Foo is not related to an
int, in the way an array of ints is.
Consider:
int y = foo[10];
The above is equivalent to:
int y_2 = *(foo + 10);
Are you sure this rhs expression does not produce UB.
foo+10 will be converted to int* then 10xsize of int added, dereferencing
will then produce UB.
In the above, we have an implicit conversion from an expression of
type "Foo" to an expression of type "int*", then a pointer arithmetic
expression, and then finally a dereference expression.
Overall, that's
struct Foo { operator int* (); };
Foo foo;
int x = *foo;
int y = foo[10];
int y_2 = *(foo + 10);
I don't see that converting a Foo to an int* is the same as an implicit
conversion of an array to a pointer.
Now, consider how an array looks:
int arr[10];
Ok big difference here. This creates an array of 10 int-type objects. The
expression Foo foo; created a single Foo-type object.
int x = *arr;
int y = arr[10];
int y_2 = *(arr + 10);
Notice how it looks exactly the same.
It doesn't look exactly the same , you have presented it a way that it
appears to be similar.
With the object 'arr', dereferencing is well defined. The expression
*(arr+n) will access the nth element of the array.
As the foo object is not an array, the expression *(foo+n) is undefined.
Notice also that the actual
expressions, conversions, and operations are basically the same as
well. The type "int[10]" has an implicit conversion to pointer just
like the type "Foo", and after that it proceeds exactly the same way.
The rest of the operations are performed on the pointer value. There
is no dereference of the array directly, just like there is no
dereference of the object foo directly. The only deferencing which
happens is the deferencing of the pointer from the implicit
conversions and resulting pointer arithmetic.
There is a big difference , please allow me to explain:
An array is a contiguous sequnece of objects of element-type. Therefore to
give an example of an array of 4 ints:
[int][int][int][int]
In a similar class-type object with 4 int-type data members, you have:
[ [int] [int] [int] [int] ]
A pointer to an array(as a whole) , is of type int(*)[4]
A pointer to the class-type , is of type T*, where T is the class-type.
Notice how the array pointer-type has a reference to the underlying
integer-type. The classs-type pointer does not have this.
There is also a big difference in the way these pointers behave when
dereferneced.:
The pointer to array-type will yield an non modifiable object, which is a
representation of the four integer objects, but this cannot be used to
access the array unless it is either (i) converted to a pointer (ii)
converted to a reference. So what is this mysterious non-modifiable object,
it it refered to as an array-type object but it is not an object which
resides in memory alongsdie the sequence of integers.
This pointer-type can also be dereferenced twice , which suggest there is
either (i) some mysterious intemedaite pointer-type object , or(ii) an extra
level of indirection.
The exact way the compiler implements this double derefernce seems undefined
and I am unsure about the exact order of conversions applied, if any.
The pointer to class-type T, will yield a T-type object, which is a
compeltely modifiable T object. This pointer-type can only be dereferneced
once and these is no mysterious intermediate object, or extra levels of
indirection. The object which can be accessed as a result of dereferencing
this pointer-type can also be accesssed(read to or written to) as a whole
object, unlike the pointer to array-type.
An array of T's has an uderlying element-type of T, This is the only type of
object that can be accessed when we dereference and array, with any of its
many identifier types.
A class-type object does not have this mysterious non modifiable object-type
, to which a pointer can be created to represent the concept of pointing to
the array( as a whole). A class-type can be pointed to as whole with the
general context of "poining to" meaning the pointed to object is accessed
when you derefernece the pointer.
I take on your point about pointers to functions not actually accesssing a
function, in the context of addressing memory. I am going to investigate
that now. I may raise a further discussion on it if I find anything
intersting.