Pointer Problem

J

Juha Nieminen

Paul said:
I think the way most people see it is that an array is a sequence of
elements of type T, so it makes sense that the pointer that points to
them is of type T*. The fancy pointer types like T(*) are of the
same type but have another level of indirection to allow for multiple
indexing .. anarray[i1][i2].


T* and T(*) are not of the same type, which becomes clear if you,
for example, look at the size of their derefenced types. In other words,
if you have a "T *p1" and a "T (*p2)[123]" then sizeof(*p1) is not the
same as sizeof(*p2). That's because p2 points to an array of
123 elements of type T while p1 points to one value of type T.

(Let your ranting begin.)
 
P

Paul

Paul said:
I think the way most people see it is that an array is a sequence of
elements of type T, so it makes sense that the pointer that points to
them is of type T*. The fancy pointer types like T(*) are of the
same type but have another level of indirection to allow for multiple
indexing .. anarray[i1][i2].


  T* and T(*) are not of the same type, which becomes clear if you,
for example, look at the size of their derefenced types. In other words,
if you have a "T *p1" and a "T (*p2)[123]" then sizeof(*p1) is not the
same as sizeof(*p2). That's because p2 points to an array of
123 elements of type T while p1 points to one value of type T.

  (Let your ranting begin.)

Ranting?


What you're saying is like saying int* and int** point to different
types. Sure if you assert them at different levels of indirection they
will appear different but regarding types, ultimately they both point
to an int type object.

If your argument would be to suggest that they point to different
types because int** points to an int* type and int* points to an int
type. I'd suggest that you are confusing the term "level of
indirection" with "type".
 
J

Juha Nieminen

Paul said:

Yes. Exactly like this:
What you're saying is like saying int* and int** point to different
types. Sure if you assert them at different levels of indirection they
will appear different but regarding types, ultimately they both point
to an int type object.

If your argument would be to suggest that they point to different
types because int** points to an int* type and int* points to an int
type. I'd suggest that you are confusing the term "level of
indirection" with "type".

You do understand that "int" and "int*" are different types, do you?
They may even have difference sizes (eg. in most 64-bit systems they do).

Likewise "int" and "int[10]" are different types. The former is an
integral while the latter is an array of 10 integrals. (Again, they have
different sizes: The former is sizeof(int) bytes big, while the latter
is 10*sizeof(int) bytes big.)

"int*" points to an "int", and "int(*)[10]" points to an array of 10 ints.
The difference becomes clear eg. when you increment those pointers (the
former will change by the size of one int, while the latter will change
by the the size of 10 ints), or take the size of what they are pointing at.

There's no way of interpreting this that would allow you to say that
"int*" and "int(*)[10]" are of the same type.
 
J

Jorgen Grahn

.
What you're saying is like saying int* and int** point to different
types. Sure if you assert them at different levels of indirection they
will appear different but regarding types, ultimately they both point
to an int type object.

If your argument would be to suggest that they point to different
types because int** points to an int* type and int* points to an int
type. I'd suggest that you are confusing the term "level of
indirection" with "type".

You may not like it, but that's the accepted terminology in C++.

You have some kind of point of course: the only reason to mess around
with int*, int** or int***** is to eventually do something to a bunch
of ints. But the language doesn't know, or care.

/Jorgen
 
P

Paul

On 23/02/2012 21:08, Paul <pchrist wrote:

By that I mean array to pointer conversion *can* happen not that array
to pointer conversion *will* happen:

int a[10];
int (*p)[10] = &a;
int (&r)[10] = *p; // no array to pointer conversion
Of course there is no array to pointer conversion because the
expression does not contain an array.
I think perhaps you are mistaking the pointer or reference types { T(*)
and T(&) respectively }, to be arrays. These are not arrays
they're pointers and references.

A pointer to an array stores only one address, usually to the first
element unless pointer arithmetic has been carried out. The difference
between pointer types does not change the type of array pointed-to,
the difference is in the level of indirection of the pointer.
 
P

Paul

On Wed, 2012-02-22, Paul wrote:

...



You may not like it, but that's the accepted terminology in C++.

AFAICT the accepted terminology in C++ is that a pointer of type T*
can point to a T or an array of T's.
You have some kind of point of course: the only reason to mess around
with int*, int** or int***** is to eventually do something to a bunch
of ints. But the language doesn't know, or care.
I was merely trying to demonstrate that different levels of
indirection do not change the object type. The object pointed to is an
int type, whether you create a pointer to it with one level of
indirection or five i.e: int*****.
The same applies to an array, the arrays' type does not change because
of the pointer type used to address it. An array of chars, for
example, is addressed using a char* because you cannot address n x
chars, you can address only one char. If you create a pointer with two
or three levels of indirection to this array of chars it doesn't
change the type of the pointed-to object.

And this is exactly what a pointer of type char(*ptr) is, a pointer
to chars with two levels of indirection. The level of indirection
doesn't affect the type of the addressed object.


Yeah sure you can be really pedantic and argue that between each level
of indirection the pointer type changes from eg: char*** to char** to
char*. But at the end of the day each of these pointers is just
another pointer variable that stores a memory address and its doesn't
really change the type of the pointed-to object. Its just changing in
levels of indirection. For example: a char**** is a pointer to a char
just the same as a char** is a pointer to a char, is it not?.
 
P

Paul

AFAICT the accepted terminology in C++ is that a pointer of type T*
can point to a T or an array of T's.
I was merely trying to demonstrate that different levels of
indirection do not change the object type. The object pointed to is an
int type, whether you create a pointer to it with one level of
indirection or five i.e: int*****.
The same applies to an array, the arrays' type does not change because
of the pointer type used to address it. An array of chars, for
example, is addressed using a char* because you cannot address  n x
chars, you can address only one char. If you create a pointer with two
or three levels of indirection to this array of chars it doesn't
change the type of the pointed-to object.
And this is exactly what a pointer of type char(*ptr) is, a pointer
to chars with two levels of indirection. The level of indirection
doesn't affect the type of the addressed object.

Yeah sure you can be really pedantic and argue that between each level
of indirection the pointer type changes from eg: char*** to char** to
char*. But at the end of the day each of these pointers is just
another pointer variable that stores a memory address and its doesn't
really change the type of the pointed-to object. Its just changing in
levels of indirection. For example: a char**** is a pointer to a char
just the same as a char** is a pointer to a char, is it not?.

No; char**** is a pointer to a char***.

You're reply is incorrect on two points:
a) The pointer may point to a char indirectly.
b) The pointer may be null and point to nothing.

The scenario , that you agree with, where char**** is a pointer to a
char*** you are considering only one level of indirection:
char**** ---- dereferneces to ---> char***.

Now considering a less simpleton mind:
char**** ---> char*** ---> char** ---> char* ---> char.


It may point to a char(indirectly) *and* a char***. You'd be incorrect
to say this is incorrect.





Just as with the pointer type int(*). You say that this is a
pointer to an array of S, and only to an array of S, all other
contexts are deemed as incorrect. But this is nonsense because:

int array1[8][10] = {0};
int array2[9][10] ={0};
int array3[10]={0};
int (*ptr1)[10];
ptr1 = array1;
ptr1 = array2;
ptr1 = &array3;


It is correct to say that ptr1 points to 3 different sized arrays and
incorrect to say that ptr1 is only a pointer to an array of 10 ints.
The pointer type can point to arrays of different sizes and not only
to an array of 10 ints. The difference between this pointer type and
an int* type is obviously in it's level of indirection. The int type
never changes from each level of indirection, only the pointer-type to
reflect that different level of indirection, as in the case with
char***, char**, char*.
 
M

Mike McCarty

I'm not sure but I think Leigh is trying to say that your notion of "indirect" is irrelevant:

typedef <something> P;
typedef P* PP;
typedef PP* PPP;
typedef PPP* PPPP;
typedef PPPP* PPPPP;

PPPPP x = ppppp();

In the end, _x_ is a pointer to something of type PPPP. As far as _x_ is concerned, it really does not matter what PPPP is. If you try to evaluate _*x_, that's a different matter but then you're really no longer talking about _x_ at that point because _*x_ evaluates to a different (tho related) type.

As for your point, well... I'm not really sure what your point is but I'm beginning to think that the two of you are in violent agreement, you just don't realize it.
 
P

Paul

Is "something a new C++ keyword"? Wtf is that shit supposed to mean?
Please don't speak to me until you've grown a brain tyvm :)

plonk.

--- Posted via news://freenews.netfront.net/ - Complaints to (e-mail address removed) ---

Hey man sorry for being a bit snappy at you. The comment about
indirection being irrelevant annoyed me a bit, on top of Leighs
constant bickering.
 
P

Paul

I'm not sure but I think Leigh is trying to say that your notion of "indirect" is irrelevant:

typedef <something> P;
typedef P*    PP;
typedef PP*   PPP;
typedef PPP*  PPPP;
typedef PPPP* PPPPP;

PPPPP x = ppppp();

In the end, _x_ is a pointer to something of type PPPP.  As far as _x_ is concerned, it really does not matter what PPPP is.  If you try to evaluate _*x_, that's a different matter but then you're really no longer talking about _x_ at that point because _*x_ evaluates to a different (tho related) type.

As for your point, well... I'm not really sure what your point is but I'mbeginning to think that the two of you are in violent agreement, you just don't realize it.

The point is that Leigh and one or two others are saying that an int(*)
is a pointer to a 1-dimensional array, and not to a 2-dim array.
Of course they are correct to say that its a pointer to a 1-dim array
in the context of the pointers' type but they are saying this is also
true in the context of what is pointed to.
It is not always correct in the context of what is pointed to , and
this is why I originally objected to Juha's post where he wrote "int*
points to an int, and int(*)[10] points to an array of 10 ints.".

With an array of ints the pointer type norammly used to point to them
is an int*, a pointer of type int(*) can also be used to point to
them but this would have an added level of indirection.

Lets describe a pointer as a variable that stores the address of an
object and thus is a variable that is used to indirectly access some
pointed-to object. So it seems like common sense that the pointed-to
object is the object which is returned(or accessed) when the pointer
is dereferenced and as with the following:

int x; /*an object.*/
int* p = &x; /*a pointer-to object x, of type int*. */
int** pp = &p; /*a pointer to p, of type int**, which also points to x
indirectly. */

The above shows pointers that differ in levels of indirection so lets
consider what Leighs argument might be regarding the last line where I
commented that pp points to x indirectly. Leigh might say that it does
not point to x and it only points to an p because this is the basis of
his argument i.e: That the pointers' type defines what is pointed to,
and it cannot point-to anything else. I could understand this argument
because when you dereference the pointer pp you access the pointer p
thus it could be said that pp only points to p, and not to x, if we
disregard the context of pointing to an object indirectly.
If the context of pointing to an object indirectly is not disregarded
Leighs argument doesn't add up at all , as we will see later.

Moving on to pointers to arrays lets consider the following:
int arr[10];
int* p = arr;
int (*pa)[10] = &arr;


In the context of what is pointed to , and not the pointers type, pa
cannot be said to directly point to the array because when we
dereference pa we do not access the array. the pointer pa needs to be
dereferenced twice to access the array so it can only be said that it
points-to the array indirectly. On the other hand p , when
dereferenced, accesses the array. Obviously, to me , they can both
point to the array but in a slightly different context because they
have different levels of indirection.
This argument , from Leighs side, is strongly based on confusing
people between the pointers' type with what is pointed-to, or in some
cases the type of the pointed-to object. But when we get down to the
nitty gritty a pointers' type does not define what is pointed-to ,
just look at a void* for evidence of this.

I am arguing that both p and pa can be said to point to the array, and
in their own contexts both are correct because an array can be seen in
two ways: as a single object or as a sequence of objects. The argument
I am opposing is that an int* cannot point to an array of ints and can
only point to one single int. I am arguing against this because it
breaks in so many ways the most obvious being that.. the pointer type
does not define the pointed-to object as I think I have explained
above.
This seems to be the argument against me: that int* points to a single
int because its type is pointer to int, int(*)[10] is a pointer to an
array of 10 ints because its pointer type is pointer to int[10] etc
etc. As I have said this argument breaks down in many ways and thus I
object to them saying it's incorrect that an int* points to an array.

Additionally Bjarne Stroustrup says in one of his books that a char*
can point to a single char or an array of chars. I think Bjarne knows
what he is talking about when it comes to C++ and I would take much
consideration before disputing what he says. Even if their(Leigh and
others who agree with him) point was eventually proven to be correct
in standardesque and legal terms , which it will never be, most of us
know that its common knowledge and acceptable terminology that an int*
can point to an array of ints.

Again I apologise for being cheeky and a bit snappy in my previous
reply but these tedious argument can get me a bit wound up at times.
HTH
Paul.
 
M

Mike McCarty

The argument
I am opposing is that an int* cannot point to an array of ints and can
only point to one single int. I am arguing against this because it
breaks in so many ways the most obvious being that.. the pointer type
does not define the pointed-to object as I think I have explained
above.

In fact, I think that's exactly the point they're trying to make: The conversion from 'int[10]' to 'int*' implies loss of information. The lost information can only be resurrected via _convention_ (e.g. begin/end range pointers, etc.), not thru the type system itself.

An example:

int a[10];
int (&b)[9] = a[1];

The C++ language dictates that this is illegal syntax, despite the fact that simple analysis shows that it is perfectly reasonable and logically correct. This is the sort of 'context' you've been referring to but this 'context' is exactly what the language does not support.

FWIW, you can always force context upon the language, see http://codepad.org/pyZzy6Ae. Not that I recommend it...

This seems to be the argument against me: that int* points to a single
int because its type is pointer to int, int(*)[10] is a pointer to an
array of 10 ints because its pointer type is pointer to int[10] etc
etc. As I have said this argument breaks down in many ways and thus I
object to them saying it's incorrect that an int* points to an array.

Given only

int* iptr = something();

all you can say definitely is that iptr either points to an object (e.g. iptr=&arr[15]) or it does not (iptr=NULL). Everything else can only be deduced from additional external information that the int* type itself does not provide.

If I've still managed to miss the point, you're going to have to forgive me..


Mike
 
P

Paul

The argument
I am opposing is that an int* cannot point to an array of ints and can
only point to one single int. I am arguing against this because it
breaks in so many ways the most obvious being that.. the pointer type
does not define the pointed-to object as I think I have explained
above.

In fact, I think that's exactly the point they're trying to make:  The conversion from 'int[10]' to 'int*' implies loss of information.  The lost information can only be resurrected via _convention_ (e.g. begin/end range pointers, etc.), not thru the type system itself.
The two pointers you compared are different levels of indirection,
It's different pointer types look:
int* pointer to a 1-dim array.
int(*)
int(*)[S1]S2]
int(*)[S1][S2][S3] pointer to a 4-dim array


These pointers are pointers to arrays of different dimensions.
The numbers that accompany the pointers are simply a multiplier for
the index, used by the compiler when the pointer is dereferenced, it
doesn't affect the type of the pointed-to object.
A 1-dim array doesn't need a multiplier. A 2-dim array doesn't need
two multipliers it only needs one. This is not "loss of information"
as you have put it, the information is not there because it's not
required.

An example:
An example:

int a[10];
int (&b)[9] = a[1];

The C++ language dictates that this is illegal syntax, despite the fact that simple analysis shows that it is perfectly reasonable and logically correct.  This is the sort of 'context' you've been referring to but this 'context' is exactly what the language does not support.

No I never brought references into the discussion.,
FWIW, you can always force context upon the language, seehttp://codepad.org/pyZzy6Ae.  Not that I recommend it...
This seems to be the argument against me: that int* points to a single
int because its type is pointer to int, int(*)[10] is a pointer to an
array of 10 ints because its pointer type is pointer to int[10] etc
etc. As I have said this argument breaks down in many ways and thus I
object to them saying it's incorrect that an int* points to an array.

Given only

int* iptr = something();

I wish you wouldn't use this default object construction syntax(or
function syntax) when assigning to pointers, because more often than
not this will not return an objects' address. An objects' address is
assigned to a pointer, not an object.
all you can say definitely is that iptr either points to an object (e.g. iptr=&arr[15]) or it does not (iptr=NULL).  Everything else can only be deduced from additional external information that the int* type itself does not provide.

A pointer doesn't only point to an object or null because it can also
point to objects(plural).
If I've still managed to miss the point, you're going to have to forgive me.

If you agree with Leighs argument , and disagree with Bjarne S, then I
think you have missed the point :)
I'm sorry if I can't present my argument well enough to make you
understand
 
M

Mike McCarty

A 1-dim array doesn't need a multiplier. A 2-dim array doesn't need
two multipliers it only needs one. This is not "loss of information"
as you have put it, the information is not there because it's not
required.

I'm not talking about multipliers, I'm talking about knowing the bounds of the underlying array. It is lost information and it is required if you want to (robustly) treat the pointer as a reference to an array of objects. How do you sensibly increment a pointer without knowing the range of values the pointer can logically take?
An example:
An example:

int a[10];
int (&b)[9] = a[1];

The C++ language dictates that this is illegal syntax, despite the factthat simple analysis shows that it is perfectly reasonable and logically correct.  This is the sort of 'context' you've been referring to but this 'context' is exactly what the language does not support.

No I never brought references into the discussion.,

References *are* pointers...

If you insist:
int a[10];
int (*b)[9] = &a[1];

The argument still holds...
I wish you wouldn't use this default object construction syntax(or
function syntax) when assigning to pointers, because more often than
not this will not return an objects' address. An objects' address is
assigned to a pointer, not an object.

I'm not sure why you'd think it was an object constructor call -- it makes more syntactic sense as a simple function call. In any case, it's pseudo-code. The RHS of the assignment is not relevant which is why I did not workvery hard at making it realistic. The point being: A _naked_ pointer cannot be (usefully) treated as an array reference.
A pointer doesn't only point to an object or null because it can also
point to objects(plural).

It can point to an object allocated as part of an array, yes. Beyond that,you need external information. If you want to be pedantic about it, you could say that all allocations are array allocations just that many of them are arrays of size 1. Does it change what you can do with pointers? Nope.Does it change the meaning of pointers? Nope.
If you agree with Leighs argument , and disagree with Bjarne S, then I
think you have missed the point :)

I'm not sure what you think Leigh's argument is at this point. I see nothing that contradicts anything Bjarne has ever said. I still contend you arein violent agreement.
 
P

Paul

A 1-dim array doesn't need a multiplier. A 2-dim array doesn't need
two multipliers it only needs one. This is not "loss of information"
as you have put it, the information is not there because it's not
required.

I'm not talking about multipliers, I'm talking about knowing the bounds of the underlying array.  It is lost information and it is required if youwant to (robustly) treat the pointer as a reference to an array of objects..  How do you sensibly increment a pointer without knowing the range of values the pointer can logically take?
An example:
An example:
int a[10];
int (&b)[9] = a[1];
The C++ language dictates that this is illegal syntax, despite the fact that simple analysis shows that it is perfectly reasonable and logicallycorrect.  This is the sort of 'context' you've been referring to but this 'context' is exactly what the language does not support.
No I never brought references into the discussion.,

References *are* pointers...


But you have said yourself that a pointer does not carry typeinfo. You
are contradicting yourself by saying that a reference is a pointer,
when it suits you.
If you insist:
int a[10];
int (*b)[9] = &a[1];

The argument still holds...
I wish you wouldn't use this default object construction syntax(or
function syntax) when assigning to pointers, because more often than
not this will not return an objects' address. An objects' address is
assigned to a pointer, not an object.

I'm not sure why you'd think it was an object constructor call -- it makes more syntactic sense as a simple function call.  In any case, it's pseudo-code.  The RHS of the assignment is not relevant which is why I did not work very hard at making it realistic.  The point being: A _naked_ pointer cannot be (usefully) treated as an array reference.
A pointer doesn't only point to an object or null because it can also
point to objects(plural).

It can point to an object allocated as part of an array, yes.

No , it can point to objects(plural) , that is what I said objectS
(plural) , not a single object that is part of something.
 Beyond that, you need external information.  If you want to be pedantic about it, you could say that all allocations are array allocations justthat many of them are arrays of size 1.  Does it change what you can do with >pointers?  Nope.  Does it change the meaning of pointers?  Nope..

You don't always need information, its a well known fact that in C and
C++ a pointer to an array does not carry size information.
All allocations aren't arrays , because an array is a sequence of
elements. Yes an array of size 1 is the same as a single object but
then that's not really an array is it, its just a single object. And
please don't bring arrays of size 0 into the discussion..
I'm not sure what you think Leigh's argument is at this point.  I see nothing that contradicts anything Bjarne has ever said.  I still contend you are in violent agreement.

Leighs argument is that an int* can only point to a single int and
cannot point to an array of ints. This contradicts what Bjarne says in
his C++ glossary re: "char* - pointer to a char or an array of char"
source: http://www2.research.att.com/~bs/glossary.html.

This is why I am objecting to Juha and Leighs argument because they
are confusing the pointers-type with what is pointed-to. The two are
different contexts of "is a pointer -to" and not always related.


If we have an object in memory that is an array, of any size: A
pointer to it is a pointer to an array regardless of its's type, or to
where it points within the array. They are incorrect to suggest that
what is pointed to is defined by the pointers type, just look at a
void pointer for an example of how wrong this is.
 
M

Mike McCarty

But you have said yourself that a pointer does not carry typeinfo. You
are contradicting yourself by saying that a reference is a pointer,
when it suits you.

What??? A reference is a (immutable) pointer with a dose of syntactic sugar. Nothing more, nothing less. This does not contradict anything I've said by evidence of the rewritten example I followed up with:
If you insist:
int a[10];
int (*b)[9] = &a[1];

The argument still holds...

I changed two characters, now it's a pointer instead of a reference, with exactly the same results. You seem to blithely ignore anything that you can't refute.
If we have an object in memory that is an array, of any size: A
pointer to it is a pointer to an array regardless of its's type, or to
where it points within the array. They are incorrect to suggest that
what is pointed to is defined by the pointers type, just look at a
void pointer for an example of how wrong this is.

Well, here is where I get off the bus.

If you have a point at all, you have been unable to sufficiently explain it to anybody and you certainly have not explained why it might be an important point for others to grasp.

I would say we'll just agree to disagree but I'm not convinced there's actually a disagreement here, despite your protests.

Good luck.

Mike
 
P

Paul

I'm not talking about multipliers, I'm talking about knowing the bounds of the underlying array.  It is lost information and it is required if youwant to (robustly) treat the pointer as a reference to an array of objects..  How do you sensibly increment a pointer without knowing the range of values the pointer can logically take?

That *multiplier* is the same thing that you are talking about.
For example:
int anarray[10][10];
int(*p)[10] = anarray;
p[5][2] = 55;

In the assignment here first index is an offset equal to 5 x
mulitplier , where the multiplier is 10. So the indexed element will
be the 50 + results of second index( which is just 2). So the element
accessed is...
index1 * multiplier + index2

This same value is used if the pointer is incremented i.e:
p++;
Here pointer to the array is incremented by 10*elements.
Obviously there is no need for this multiplier with a 1-dim array, it
would always be 1.

Perhaps now you understand why a pointer to a 1-dim array is normally
of type int* and we don't need added info for incrementing or
indexing.
 
P

Paul

But you have said yourself that a pointer does not carry typeinfo. You
are contradicting yourself by saying that a reference is a pointer,
when it suits you.

What???  A reference is a (immutable) pointer with a dose of syntactic sugar.  Nothing more, nothing less.  This does not contradict anything I've said by evidence of the rewritten example I followed up with:


If you insist:
int a[10];
int (*b)[9] = &a[1];
The argument still holds...

I changed two characters, now it's a pointer instead of a reference, withexactly the same results.  You seem to blithely ignore anything that youcan't refute.
If we have an object in memory that is an array, of any size: A
pointer to it is a pointer to an array regardless of its's type, or to
where it points within the array. They are incorrect to suggest that
what is pointed to is defined by the pointers type, just look at a
void pointer for an example of how wrong this is.

Well, here is where I get off the bus.

If you have a point at all, you have been unable to sufficiently explain it to anybody and you certainly have not explained why it might be an important point for others to grasp.

I would say we'll just agree to disagree but I'm not convinced there's actually a disagreement here, despite your protests.

Good luck.

Mike

I don't see what your point is you seem to be going of on a new
tangent about pointers and references.
I don't even know what your argument is , you seem to agree with Leigh
and Juha when they state that an int* cannot point to an array of
ints. My position is crystal clear and I have no qualms about
disagreeing with them on this because I know that in C++ the int* is
the correct type of pointer to point to a 1-dim array of ints. The
situation is not that a pointers-type defines what is pointed-to as
they describe as the only correct way.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,197
Latest member
ScottChare

Latest Threads

Top