Problem with array objects

P

Paul

A. Bolmarcich said:
[snip]

What is accessed when you dereference pparr once?

The array named arr (the value &arr has been assigned to pparr).

These are two different things.
Dereferencing pparr gives you arr, that is an array-type object , not &arr.

Are you incapable of using a compiler to find this out?

No, I'm capable. Here is an example program.

#include <iostream>
#include <typeinfo>
int main() {
int arr[4], (*pparr)[4]=&arr;

std::cout<<"typeid(arr)"<<
((typeid(arr)==typeid(*pparr))?"==":"!=")<<
"typeid(*pparr)"<<std::endl;
std::cout<<"&arr"<<((&arr==&(*pparr))?"==":"!=")<<
"&(*pparr)"<<std::endl;
}

The output I get is

typeid(arr)==typeid(*pparr)
&arr==&(*pparr)

the results of the expressions arr and *pparr have the same type
and the same address; the results are the same object: the array
named arr.
Typeid gives a string representation of an object TYPE, not an object.
Its not the array of integer objects, its another object. It's an array-TYPE
object which decays into a pointer.
Dereferencing pparr does not access the array of integer objects, it
accesses another object which decays into a pointer.

The array-type object can only be reperesented in a limited amount of ways :
1) typeinfo represents it as a string in the form of "int[]"
2) sizeof represents this as an integer value.
3) Almost any other operation will cause it to be converted to a pointer,
and its value will be an address.


An array-type object is not a figment of my imagination it exists in C++.
Why do you refuse to accept that there is such an entity as an array-type
object?

I'm not unreasonable. I have answered your questions, both here and
in other posts. I have also responed to questionable statements that
you have made and have given reasons that support my claims.
You are being unreasonable because you cannot accept that dereferencing
pparr doesn''t actually access the array but it gives access to an
array-type object.

All that code you posted above is uneccessary bullshit to try an show things
how you want them to appear.
simply coding :

std::cout<< *pparr;

is enough to prove that dereferencing pparr doesnt access the array, it
accesses and object which decays into a pointer.
I have stated numerous times that it is an array-TYPE object. So why dont
you understand when you do :

std::cout<< typeid(*pparr).name();

An array-TYPE is displayed. It's a TYPE not an OBJECT that is displayed by
typeid. The object that arr is, is an array-type object, which decays into a
pointer to the actuall array of integer objects.




[snip]
Its consistent with **** all you arsehole.
THere is **** all that is consistent about dereferencing pparr twice and
arr
once, except that it proves they are different levels of indirection.
WHich
is what I have been telling you all along.

I have never claimed that they have the same level of indirection.
Apparently you stopped reading what I wrote at the word "consistent"
and did not read what I actually wrote what dereferencing pparr twice
and arr once both resulting in the first element of the array is
consistent with.

But we are not arguing about what dereferencing ppar twice and arr once is.
We are aguing about the fact that dereferencing pparr ONCE points a
array-type object which stores an address, and it does not access the array
of integer objects.

You claimed that there is no intermediate object and there is only one array
object, but you are incorrect. There is an array-type object and an array of
integer objects which are not stored in the same memory location They are
different entities or objects or whatever you want to call them, they are
different fucking things altogether.

The array named arr (the value &arr has been assigned to pparr).
Ok so what is this object that 'arr' represents , do you accept that it is
an array-type object( which decays into a pointer) or do you still think
it's the array of integer objects?

What I have stated is that dereferencing pparr once accesses the
array named arr in the same sense as using the identifier arr.

It doesn't access THE array, It is dereferencing a pointer to an array-type
object. It accesses an array-type object which when accessed decays into
another pointer.

Ok with the following code:
int arr[3] = {1,2,3};
int (*pparr)[3] = &arr;
std::cout<<*pparr;

If dereferencing pparr once accessed the array then it would output 1.
It doesn't because it doesn't access the array, it accesses an array-TYPE
object, which decays into another pointer.
Here is what I wrote that you silently snipped.
It doesn't matter what you wrote if you're disagreeing, with what I wrote in
caps, you are wrong.
pparr is a level of indirection from arr. Dereferencing pparr
accesses an array in the same sense as using arr accesses an array,
just as given the declaration

int i, *pi = &i;

dereferencing pi accesses an int in the same sense that using i
accesses an int.

pi needs to be dereferenced twice to access the array, i needs to be , and
can only be, dereferenced once.

It is completely incorrect to suggest that, when dereferencing, they access
the array in the same way.

I am neither. I have supported my claims with quotes from the C++
standard, sample C++ programs, and assembler source generated by
a C++ compiler. What I have not done is call someone stupid or
an arsehole, as you have done.


I accept facts, such as what is actually in the C++ standard and the
output of C++ programs. I have used those as reasons that support
what I have claimed.

You don't accept the facts. You continue to claim that dereferencing pparr
accesses the array of integer objects and refuse to accept that it actually
accesses another object which is an array-type object that decays into a
pointer..
 
P

Paul

A. Bolmarcich said:
The result of dereferencing pparr once being arr is what I have
been stating. The result of the expression pparr is &arr (the
value to which pparr has been initialized). The results of
dereferencing pparr is arr.

No you are confused. &arr is an operation being carried out on arr. pparr is
a pointer.
Dereferencing pparr gives access to an array-type object(arr).
This object decays into a pointer , in most situations.
Are you incapable of using a compiler to find this out?

No, I'm capable. Here is an example program.

#include <iostream>
#include <typeinfo>
int main() {
int arr[4], (*pparr)[4]=&arr;

std::cout<<"typeid(arr)"<<
((typeid(arr)==typeid(*pparr))?"==":"!=")<<
"typeid(*pparr)"<<std::endl;
std::cout<<"&arr"<<((&arr==&(*pparr))?"==":"!=")<<
"&(*pparr)"<<std::endl;
}

The output I get is

typeid(arr)==typeid(*pparr)
&arr==&(*pparr)

the results of the expressions arr and *pparr have the same type
and the same address; the results are the same object: the array
named arr.
Typeid gives a string representation of an object TYPE, not an object.
Its not the array of integer objects, its another object. It's an
array-TYPE
object which decays into a pointer.
Dereferencing pparr does not access the array of integer objects, it
accesses another object which decays into a pointer.

The result of typeid(arr), is a std::type_info object representing
the type of arr. The fact that

typeid(arr)==typeid(*pparr)

indicates that arr and *pparr have the same type.

This is not telling us what pparr points to , it points to an object, not a
type, and that object is not a type_info object.

The return value of the name() member function of class
std::type_info is a C-string whose implementation defined value
represents the name of the type. With the GNU C++ compiler that I
use, the result of both typeid(arr).name() and typeid(*pparr).name()
is "A4_i". That is, both arr and *pparr are an array of 4 int.

In some contexts an array, such as the result of the expression
arr or *pparr, is implicltly converted to a pointer to the first
element of the array. A result that is an array of integers
object "decays into" a pointer to the first integer of the array.

You are confused what does typeinfo have to do with anything?
The array-type object can only be reperesented in a limited amount of
ways :
1) typeinfo represents it as a string in the form of "int[]"
2) sizeof represents this as an integer value.
3) Almost any other operation will cause it to be converted to a pointer,
and its value will be an address.

In this case, the array-type object is the array named arr. As I
wrote just above, the value of typeid(arr).name() with the C++
compiler that I use is "A4_i", which denotes an array of 4 int.
The value of sizeof(arr) is 16, with the C++ compiler that I use
the sizeof(int) is 4, making the size of an array of 4 int 16. In
some contexts array-to-pointer conversion is implicitly applied to
an array and the result of that conversion is a pointer to the
first element of the array.
The value of sizeof(arr) has nothing to do with the values stored in the
array.
I don't accept that there is an array-type object different from the
array because, as far as I can tell, there is nothing the C++
standard about there being such an array-type object different from
the array. If you think there is something in the C++ standard
about it, please cite the specific paragraphs about an "array-type
object" different from an array.
I dont need any standard to confirm what is comon sense. Dereferencing pparr
does not access the array of integer objects, it accesses an array-TYPE
object which is converted to a pointer in most cases.

In addition, I have posted the assembler file generated by a C++
compiler for an example program. That assembler file does not
contain an "array-type object" different from the array. That
example program and assembler output are also later in this post.
What does asm have to do with anything?


I am being reasonable; I have given the reasons why dereferencing
pparr accesses an array in the same sense as using the identifier of
the array. In this case, the array-type object that results from
dereferencing pparr is the array named arr.
But it doesn't access the array. You cannot access the array of integer
objects by dereferencing pparr once, you MUST dereference it twice.
What I have shown is consistent with what is in the C++ standard
and the behavior of C++ compilers that I have used. You are the
one who is trying to show things how you want them to appear, such
as there being an array-type object distinct from the array.

You have shown nothing but refusal to acknowledge the fact that
dereferencing pparr doesn't access the array.

Apparently, you are drawing too close of a parallel between the
expression

**pparr

Apparently this has nothing to do with my understanding of the word
"parallel".
Perhaps you have your own meaning for this word.
with the declarations

int arr[4], (*pparr)[4] = &arr;

and the expression

**ppi

with the declarations

int i, *pi = &i, **ppi = &pi;

In the latter case there are three objects: i, pi, and ppi. Between
ppi and i there is an object (named pi) that stores a pointer to int.
There are no objects here there is just your text and it shows only you
cannot accept that dereferencing pparr does not acces the array.
In the former case there are two objects: arr and pparr. Between
pparr and the int that is the first element of arr there is no
third object that stores a pointer to an int.
Blah blah, you are incorrect.

What happens in this case is an implicit array-to-pointer conversion
from the array result of *pparr to a pointer to the first element of
the array. In other words: dereferencing pparr accesses the array
and the array decays into a pointer to the first element of the array.

The result of the array-to-pointer conversion is used as the argument
in a call to the <<(const void*) member function of the ostream named
cout.

blah blah .
That's right, typeid(*pparr).name() is a C-string that represents
the name of an array type, "A4_i" with the GNU C++ compiler that I
use. It is the type of the result of the expression *pparr. The
result of the expression *pparr is an array of 4 int. That array is
subject to array-to-pointer conversion, and the result of that
conversion is a pointer to the first element of the array. The
result that conversion is not a pointer to the array.
All this deduced from a string?
My you are smart, NOT.
[snip]

The fact that dereferencing pparr twice and arr once both result in
the first element of the array is consistent
Its consistent with **** all you arsehole.
THere is **** all that is consistent about dereferencing pparr twice
and
arr
once, except that it proves they are different levels of indirection.
WHich
is what I have been telling you all along.

I have never claimed that they have the same level of indirection.
Apparently you stopped reading what I wrote at the word "consistent"
and did not read what I actually wrote what dereferencing pparr twice
and arr once both resulting in the first element of the array is
consistent with.

But we are not arguing about what dereferencing ppar twice and arr once
is.
We are aguing about the fact that dereferencing pparr ONCE points a
array-type object which stores an address, and it does not access the
array
of integer objects.

Because pparr is a pointer to an array, the result of dereferencing
pparr is an array, just as the result of dereferencing a pointer to
an int is an int. The array that results by dereferencing pparr is
the array named arr, not a different object which stores an address.

An example program I gave in a previous post was

int arr[4] = {1,2,3,4};
int (*pparr)[4] = &arr;

int foo() {
return **pparr;
}

I dont see what you are arguing about , its simple:
I think dereferencing pparr once does not access the array, you think it
does.
Its plain and simple you are incorrect.

<snip>
 
P

Paul

A. Bolmarcich said:
I'm not confused. pparr is a pointer to an array; pparr has been
initialized to &arr; the result of dereferencing pparr is arr. This
is just like given the declaration

int i, *pi = &i;

pi is a pointer to an int; pi has been initialized to &i; the result
dereferencing pi is i.
Its not the same , a single integer is exactly a single integer. An array of
integers is an array of integers.
An array of integers cannot be addressed simultaneously, the array can only
be represented by a type, that is an array-type object, which is what arr
is.
This array-type object is basically an object that is stored as a pointer on
most, if not all, implementations.

Are you incapable of using a compiler to find this out?

No, I'm capable. Here is an example program.

#include <iostream>
#include <typeinfo>
int main() {
int arr[4], (*pparr)[4]=&arr;

std::cout<<"typeid(arr)"<<
((typeid(arr)==typeid(*pparr))?"==":"!=")<<
"typeid(*pparr)"<<std::endl;
std::cout<<"&arr"<<((&arr==&(*pparr))?"==":"!=")<<
"&(*pparr)"<<std::endl;
}

The output I get is

typeid(arr)==typeid(*pparr)
&arr==&(*pparr)

the results of the expressions arr and *pparr have the same type
and the same address; the results are the same object: the array
named arr.
Typeid gives a string representation of an object TYPE, not an object.
Its not the array of integer objects, its another object. It's an
array-TYPE
object which decays into a pointer.
Dereferencing pparr does not access the array of integer objects, it
accesses another object which decays into a pointer.

The result of typeid(arr), is a std::type_info object representing
the type of arr. The fact that

typeid(arr)==typeid(*pparr)

indicates that arr and *pparr have the same type.

This is not telling us what pparr points to , it points to an object, not
a
type, and that object is not a type_info object.

According to the C++ standard when typeid is applied to an expression,
the result refers to a type_info object representing the type of the
expression. The output line

typeid(arr)==typeid(*pparr)

of the above program indicates that arr and *pparr have the same type.
The output line

&arr==&(*pparr)

of the above program indicates that pparr points to the object named
arr.
I don't need the C++ standard to understand that typeid gives information
about the TYPE, the name is kinda self explanatory.
I have told you it's an array-type object on many occassions.

The object pointed to by pparr is an array-type object, that decays into a
pointer.


You are confused what does typeinfo have to do with anything?

What typeid has to do with it is that I posted the above program that
compares the typeid and address of arr and *pparr because you wrote:

Are you incapable of using a compiler to find this out?

That was in a reply to what I wrote:

The results of dereferencing pparr once being arr is what I have
been stating. The result of the expression pparr is &arr (the
value to which pparr has been initialized). The results of
dereferencing pparr is arr.

I posted a program that showed that arr and *pparr have the same
type and the same address. Because they have the same type and
same address, the result of dereferencing pparr is arr. I posted
the program to support a claim I made that you questioned. You
asked a question, I gave a detailed answer.
The array-type object can only be reperesented in a limited amount of
ways :
1) typeinfo represents it as a string in the form of "int[]"
2) sizeof represents this as an integer value.
3) Almost any other operation will cause it to be converted to a
pointer,
and its value will be an address.

In this case, the array-type object is the array named arr. As I
wrote just above, the value of typeid(arr).name() with the C++
compiler that I use is "A4_i", which denotes an array of 4 int.
The value of sizeof(arr) is 16, with the C++ compiler that I use
the sizeof(int) is 4, making the size of an array of 4 int 16. In
some contexts array-to-pointer conversion is implicitly applied to
an array and the result of that conversion is a pointer to the
first element of the array.
The value of sizeof(arr) has nothing to do with the values stored in the
array.

I never claimed it did. The value of sizeof(arr) is the number of
bytes in the object named arr.

So why have you meantioned sizeof?
What does that have to do with accessing the array?

You claim that dereferencing pparr once accesses the array but it doesn't,
and you are just now trying to obscure the whole argument by introducing
nonsnese about typeid and sizeof.
Because we are discussing C++, what matters is what is in the C++
standard. The C++ standard specifies requirements for
implementations of the C++ programming language. If what is in
the C++ standard is different than someone's common sense, what
is correct for an implementation of C++ is what is in the standard.

The result of dereferencing a pointer to an array is an array. The
type of that result is an array type. As with all array results, in
some contexts array-to-pointer conversion is applied, and the result
of that conversion is a pointer to the first element of the array.
You refuse to acknowledge that an array has different levels of indirection.
You seem to think that only one exists.
The term "array" can mean different things:
a) An array of integer type objects.
b) An array type object.

The above have different levels if indirection.
You only see (b) as an acceptable meaning for "array", which is incorrect
and narrow minded.

A pointer to an "array" of integer objects is a pointer of type int*.
A pointer to an "array" of array-type objects is a pointer of type int(*)[]
To someone who understands it, it shows that the example C++
program does not contain an array-type object different from the
array. I posted the example program to support my claim that
there is not an array-type object different from the array.
You don't seem to understand that, in asm, an array is just a pointer.

Dereferencing pparr twice accesses the first element of the array.
Accessing an element of an array is not the same as accessing the
array, because an element of an array and the array have different
types.
You cannot access a whole array simultaneously.
You can only access a single element.

What I have shown supports my claim: "Dereferencing pparr accesses
an array in the same sense that using the name arr accesses an
array." If you want to claim that they don't both access the
array in the same sense, please support your claim, for example by
citing paragraph(s) in the C++ standard or with a C++ program.
Dereferencing pparr once does not access the array, dereferencing it twice
does.
Dereferencing arr once does access the array, arr cannot be dereferenced
twice.

A standard meaning of the word parallel is: "a person or thing that
is similar or analogous to another" (from
http://oxforddictionaries.com/view/entry/m_en_gb0604160#m_en_gb0604160).
**pparr is similar to **ppi (in the continuation of what I wrote,
below); they both have ** followed by an identifier.
Sorry but I still don't have a clue what you are talking about.
with the declarations

int arr[4], (*pparr)[4] = &arr;

and the expression

**ppi

with the declarations

int i, *pi = &i, **ppi = &pi;

In the latter case there are three objects: i, pi, and ppi. Between
ppi and i there is an object (named pi) that stores a pointer to int.
There are no objects here there is just your text and it shows only you
cannot accept that dereferencing pparr does not acces the array.

According to the C++ standard: an object is created by a definition.
The statement

int i, *pi = &i, **ppi = &pi;

is a definition of three objects, while the statement

int arr[4], (*pparr)[4] = &arr;

is a definition of two objects.

No its 6 objects.

And:
int arr[5]={0};

Is the defintion of one array-type object, and 5 integer objects.


Blah blah, you are incorrect.

On my, a claim about me being incorrect without any supporting
reasons. That is a difference between us, I support my claims, such
as with above example of the difference between **pparr and **ppi.

[snip]

On my, its not a claim its a fact.
 
P

Paul

A. Bolmarcich said:
A. Bolmarcich said:
On 2011-05-18, Paul <[email protected]> wrote:
[snip]
I'm not confused. pparr is a pointer to an array; pparr has been
initialized to &arr; the result of dereferencing pparr is arr. This
is just like given the declaration

int i, *pi = &i;

pi is a pointer to an int; pi has been initialized to &i; the result
dereferencing pi is i.
Its not the same , a single integer is exactly a single integer. An array
of
integers is an array of integers.
An array of integers cannot be addressed simultaneously, the array can
only
be represented by a type, that is an array-type object, which is what arr
is.
This array-type object is basically an object that is stored as a pointer
on
most, if not all, implementations.

That's right, an integer is an integer, and the result of
dereferencing a pointer to an integer is an integer. Similarly, an
array of integers is an array of integers, and the result of
dereferencing a pointer to an array of integers is an array of
integers. I don't know of anything in the C++ standard that
states otherwise.

When you dereference a pointer to int you access the pointed to integer
object like so :
int x=5;
int* px = &x;
std::cout<< *px;
//this will output 5 because dereferencing px accesses the object it points
to.


With an array the situation is not the same becasue an array cannot be
accessed, as a whole. The only way we can point to an array is to point to
one of its elements.
int arr[3] = {1,2,3};
int* parr = arr;
int (*pparr)[3] = &arr;

std::cout<< *parr;
//outputs 1 because it points to the first element of the array.
std::cout<<*pparr;
//outputs a memory address because it points to an array-type object.

An array identifier such as 'arr' is an array-type object. A pointer to this
object points to a single object, not to an array of thi sobject type.

Given the declaration

int arr[4];

a C++ implementaion creates an array object to represent the array,
but it does not also create an object that stores a pointer to the
array object, unless one is explicitly present, say due to the
declaration

int (*pparr)[4] = &arr;

Due to that statement a C++ implementation creates a pointer to
array object that is initialized to point to the array. The
pointer points directly to the array object.

The pointer pparr above points to a single object not an array of objects.
Consider this:

int (*p)[3]=0;
std::cout<<*p<<std::endl;
std::cout<< typeid(*p).name()<<std::endl;
std::cout<< sizeof(*p);

Does the above pointer point to a valid object?
Or is it completely UB because its dereferencing a null pointer?

A few followups ago I posted the code generated by a GNU C++ compiler
to show how an array object and a pointer to an array object were
implemented. I don't know of any compiler that adds an object that
stores a pointer to the array for each array. I don't know of
anything in the C++ standard that requires an object that stores
a pointer to an array for each array. If you do, please provide
details.
An array object must store a pointer otherwise how does it know, where in
memory, the array is?

Are you incapable of using a compiler to find this out?

No, I'm capable. Here is an example program.

#include <iostream>
#include <typeinfo>
int main() {
int arr[4], (*pparr)[4]=&arr;

std::cout<<"typeid(arr)"<<
((typeid(arr)==typeid(*pparr))?"==":"!=")<<
"typeid(*pparr)"<<std::endl;
std::cout<<"&arr"<<((&arr==&(*pparr))?"==":"!=")<<
"&(*pparr)"<<std::endl;
}

The output I get is

typeid(arr)==typeid(*pparr)
&arr==&(*pparr)

the results of the expressions arr and *pparr have the same type
and the same address; the results are the same object: the array
named arr.
Typeid gives a string representation of an object TYPE, not an
object.
Its not the array of integer objects, its another object. It's an
array-TYPE
object which decays into a pointer.
Dereferencing pparr does not access the array of integer objects, it
accesses another object which decays into a pointer.

The result of typeid(arr), is a std::type_info object representing
the type of arr. The fact that

typeid(arr)==typeid(*pparr)

indicates that arr and *pparr have the same type.

This is not telling us what pparr points to , it points to an object,
not
a
type, and that object is not a type_info object.

According to the C++ standard when typeid is applied to an expression,
the result refers to a type_info object representing the type of the
expression. The output line

typeid(arr)==typeid(*pparr)

of the above program indicates that arr and *pparr have the same type.
The output line

&arr==&(*pparr)

of the above program indicates that pparr points to the object named
arr.
I don't need the C++ standard to understand that typeid gives information
about the TYPE, the name is kinda self explanatory.
I have told you it's an array-type object on many occassions.

The object pointed to by pparr is an array-type object, that decays into
a
pointer.

Avoiding the term "array-type" that you use but the C++ standard
doesn't: the object pointed to by pparr is an array. The type of
the object pointed to is an array of int. As with all arrays in C++,
in some contexts, array-to-pointer conversion is implicitly applied
and the result of the conversion is a pointer to the first element of
the array.
No the C++ standard states its an array type object.

The object pointed to is an array TYPE.



<snip>
 
P

Paul

Actually I should've said array *type* object.

That is the object that stores the address when we do this:
int arr[43];
int* pntrto_array_of_intgr_objs = arr;

The object 'arr' must store the address of the array someplace.
Wrong. An array object does not store a pointer to itself just like an
"int" object does not store a pointer to itself. Get a clue. It does not
need to store a pointer to itself to "know" where in memory it (or its
elements) preside; for example the compiler knows where an array object
(or its elements) are on the stack relative to the stack frame pointer;
this information is determined at compile time not runtime.

If you want a pointer to an array then use a .. wait for it .. pointer to
an array:

int array[42];
int (*pointer_to_an_array)[42] = &array;

You naming is inaccurate what it should be is pointerto_one_single_arrayobj.
 
P

Paul

Leigh Johnston said:
Leigh Johnston said:
On 23/05/2011 22:53, Paul wrote:
An array object must store a pointer otherwise how does it know, where
in memory, the array is?
Actually I should've said array *type* object.

That is the object that stores the address when we do this:
int arr[43];
int* pntrto_array_of_intgr_objs = arr;

The object 'arr' must store the address of the array someplace.

No it mustn't. Read my initial reply again:
Yes it must how can we do this :
int arr[6];
int* p = arr;

arr must hold the address of the array or how can it be convered to a
pointer?
Do you think this value is plucked out of thin air?

<snip>
 
P

Paul

Leigh Johnston said:
An array object must store a pointer otherwise how does it know,
where
in memory, the array is?
Actually I should've said array *type* object.

That is the object that stores the address when we do this:
int arr[43];
int* pntrto_array_of_intgr_objs = arr;

The object 'arr' must store the address of the array someplace.

No it mustn't. Read my initial reply again:
Yes it must how can we do this :
int arr[6];
int* p = arr;

arr must hold the address of the array or how can it be convered to a
pointer?

Wrong; arr does not hold the address of the array; arr *is* the array.
Do you think this value is plucked out of thin air?

The compiler knows the address of the array relative to something else
(such as a stack frame pointer or a 'this' pointer). Again if you want
something that holds the address of the array then you want a pointer to
an array (as I said above).

What you say doesn't make sense. You say the compiler KNOWS the address of
the array(whether it be a relative address or otherwise is irrelevant).
How does it KNOW this address? It cannot KNOW this address unless it stores
it someplace.

So where is this address stored and how does the compiler know where to find
this stored address, if arr does not store it?


<snip>
 
P

Paul

Leigh Johnston said:
An array object must store a pointer otherwise how does it know,
where
in memory, the array is?
Actually I should've said array *type* object.

That is the object that stores the address when we do this:
int arr[43];
int* pntrto_array_of_intgr_objs = arr;

The object 'arr' must store the address of the array someplace.

No it mustn't. Read my initial reply again:

Yes it must how can we do this :
int arr[6];
int* p = arr;

arr must hold the address of the array or how can it be convered to a
pointer?

Wrong; arr does not hold the address of the array; arr *is* the array.

Do you think this value is plucked out of thin air?

The compiler knows the address of the array relative to something else
(such as a stack frame pointer or a 'this' pointer). Again if you want
something that holds the address of the array then you want a pointer
to an array (as I said above).

What you say doesn't make sense. You say the compiler KNOWS the address
of the array(whether it be a relative address or otherwise is
irrelevant).
How does it KNOW this address? It cannot KNOW this address unless it
stores it someplace.

What I said makes perfect sense if you are not dense. The address is
calculated using an offset to something else (such as a stack frame
pointer or a 'this' pointer). For example for an array on the stack the
compiler KNOWS that array element n is located at stack frame pointer + o
bytes; if n is a constant then o can be a constant known at compile time;
if n is not a constant then all we need is a simple effective address
calculation involving the stack frame pointer, n and the sizeof an element
to determine the address of element n.
The address cannot be calculated with random numbers. The address must be
known, whether it is known as an offset or a real address is irrelevant.
This known address must be stored in an object someplace.
There is no address stored; there is no difference between how the address
of an array object is calculated and how the address of any other kind of
object is calculated: there is nothing special about arrays. The address
of an array or an array element is calculated at runtime using an
effective address calculation involving some other pointer (stack frame
pointer or a 'this' pointer).

It doesn't matter if it is an offset or a real address, the offset value
must be stored to be known, it cannot just be magically KNOWN by the
compiler.


<snip>
 
I

Ian Collins

The address cannot be calculated with random numbers. The address must be
known, whether it is known as an offset or a real address is irrelevant.
This known address must be stored in an object someplace.

On most common implementations, that place is the (or a) stack pointer.

Why do find this so hard? or are you being deliberately obtuse?

If I write "int n;" do you expect there to be some mythical object
storing the address of n?

Now here's the big one:

If there is an object that stores the address, where is the address of
that object stored?
 
P

Paul

Ian Collins said:
On most common implementations, that place is the (or a) stack pointer.

Why do find this so hard? or are you being deliberately obtuse?

If I write "int n;" do you expect there to be some mythical object storing
the address of n?
But this is not the same :

int n;
int* arr[5];

std::cout<< n <<std::endl << arr;


An integer will output an integer value , an array will output a memory
address.
An integer object is not the same as an array object in the context of this
discussion.



Now here's the big one:

If there is an object that stores the address, where is the address of
that object stored?
Yes thats about as big as your ****, and that's not very big at all.
:)
 
P

Paul

Leigh Johnston said:
An array object must store a pointer otherwise how does it know,
where
in memory, the array is?
Actually I should've said array *type* object.

That is the object that stores the address when we do this:
int arr[43];
int* pntrto_array_of_intgr_objs = arr;

The object 'arr' must store the address of the array someplace.

No it mustn't. Read my initial reply again:

Yes it must how can we do this :
int arr[6];
int* p = arr;

arr must hold the address of the array or how can it be convered to a
pointer?

Wrong; arr does not hold the address of the array; arr *is* the array.

Do you think this value is plucked out of thin air?

The compiler knows the address of the array relative to something else
(such as a stack frame pointer or a 'this' pointer). Again if you want
something that holds the address of the array then you want a pointer
to an array (as I said above).

What you say doesn't make sense. You say the compiler KNOWS the address
of the array(whether it be a relative address or otherwise is
irrelevant).
How does it KNOW this address? It cannot KNOW this address unless it
stores it someplace.

What I said makes perfect sense if you are not dense. The address is
calculated using an offset to something else (such as a stack frame
pointer or a 'this' pointer). For example for an array on the stack
the compiler KNOWS that array element n is located at stack frame
pointer + o bytes; if n is a constant then o can be a constant known
at compile time; if n is not a constant then all we need is a simple
effective address calculation involving the stack frame pointer, n and
the sizeof an element to determine the address of element n.
The address cannot be calculated with random numbers. The address must
be known, whether it is known as an offset or a real address is
irrelevant.
This known address must be stored in an object someplace.
So where is this address stored and how does the compiler know where to
find this stored address, if arr does not store it?

There is no address stored; there is no difference between how the
address of an array object is calculated and how the address of any
other kind of object is calculated: there is nothing special about
arrays. The address of an array or an array element is calculated at
runtime using an effective address calculation involving some other
pointer (stack frame pointer or a 'this' pointer).

It doesn't matter if it is an offset or a real address, the offset value
must be stored to be known, it cannot just be magically KNOWN by the
compiler.

Asserting falsehoods just makes you look dense. The offset can be
"stored" in the text segment. R E A D A B O O K .

Its an object stored in memory regardless of what segment it is stored in.
 
J

Joshua Maurice

Yes thats about as big as your ****, and that's not very big at all.
:)

Ok. A good legitimate question, and he entirely avoids it. He has to
be a troll, or he's so hopelessly gone. Either way, I feel bad now
about replying in such detail to him recently. I would just feel bad
if someone else came along and read this, thinking that Paul knows
what he's talking about.

Duty Calls
http://xkcd.com/386/

Ugg. This is supposed to be a useful resource for others, right?
Suppose I'll have to strike the right balance. Correct him once a
thread if he doesn't spam, and ignore him when he does spam.
 
P

Paul

Leigh Johnston said:
On 25/05/2011 00:12, Paul wrote:
An array object must store a pointer otherwise how does it
know,
where
in memory, the array is?
Actually I should've said array *type* object.

That is the object that stores the address when we do this:
int arr[43];
int* pntrto_array_of_intgr_objs = arr;

The object 'arr' must store the address of the array someplace.

No it mustn't. Read my initial reply again:

Yes it must how can we do this :
int arr[6];
int* p = arr;

arr must hold the address of the array or how can it be convered
to a
pointer?

Wrong; arr does not hold the address of the array; arr *is* the
array.

Do you think this value is plucked out of thin air?

The compiler knows the address of the array relative to something
else
(such as a stack frame pointer or a 'this' pointer). Again if you
want
something that holds the address of the array then you want a
pointer
to an array (as I said above).

What you say doesn't make sense. You say the compiler KNOWS the
address
of the array(whether it be a relative address or otherwise is
irrelevant).
How does it KNOW this address? It cannot KNOW this address unless it
stores it someplace.

What I said makes perfect sense if you are not dense. The address is
calculated using an offset to something else (such as a stack frame
pointer or a 'this' pointer). For example for an array on the stack
the compiler KNOWS that array element n is located at stack frame
pointer + o bytes; if n is a constant then o can be a constant known
at compile time; if n is not a constant then all we need is a simple
effective address calculation involving the stack frame pointer, n and
the sizeof an element to determine the address of element n.

The address cannot be calculated with random numbers. The address must
be known, whether it is known as an offset or a real address is
irrelevant.
This known address must be stored in an object someplace.


So where is this address stored and how does the compiler know
where to
find this stored address, if arr does not store it?

There is no address stored; there is no difference between how the
address of an array object is calculated and how the address of any
other kind of object is calculated: there is nothing special about
arrays. The address of an array or an array element is calculated at
runtime using an effective address calculation involving some other
pointer (stack frame pointer or a 'this' pointer).

It doesn't matter if it is an offset or a real address, the offset
value
must be stored to be known, it cannot just be magically KNOWN by the
compiler.

Asserting falsehoods just makes you look dense. The offset can be
"stored" in the text segment. R E A D A B O O K .

Its an object stored in memory regardless of what segment it is stored
in.

An offset is not an object; an offset can be embedded in the machine code
in the text segment where it is used to calculate the address of an object
when added to some other pointer such as a stack frame pointer or a 'this'
pointer.

int arr[6];
std::cout<< arr;

The above outputs a memory address, whether you think this is an offset
embedded in machine code or it is stored in the XXXX segment is quite
irrellevant.
I tihnk you are speaking nonsense. It wouldn't be the first time.
 
P

Paul

Yes thats about as big as your ****, and that's not very big at all.
:)

--Ok. A good legitimate question, and he entirely avoids it. He has to
--be a troll, or he's so hopelessly gone. Either way, I feel bad now
--about replying in such detail to him recently. I would just feel bad
--if someone else came along and read this, thinking that Paul knows
--what he's talking about.

If you think this is a legitimate point please raise it in the new thread
and I will address it.
This is a place where you can hide so why are you discussing here when there
is a new thread that directly addresses this point?
 
P

Paul

Leigh Johnston said:
Asserting falsehoods just makes you look dense. The offset can be
"stored" in the text segment. R E A D A B O O K .


Its an object stored in memory regardless of what segment it is
stored in.


An offset is not an object; an offset can be embedded in the machine
code in the text segment where it is used to calculate the address of
an object when added to some other pointer such as a stack frame
pointer or a 'this' pointer.

int arr[6];
std::cout<< arr;

The above outputs a memory address, whether you think this is an offset
embedded in machine code or it is stored in the XXXX segment is quite
irrellevant.

Of course it is relevant; it is relevant to a discussion in which you
claim that an array identifier somehow "stores" a memory address which is
plainly absurd.
I'm obviously talking about an array type object , as described in the C+
standards ref:

"[ Note: conversions affecting expressions of array type are described in
4.2. Objects of array types cannot be modified, see 3.10. -end note ]"


I don't know why you think this is so "absurd".
And why you feel the need to babble on about machine code, text segments,
stack pointers, and offsets is beyond me.


<snip>
 
T

Thomas David Rivers

Paul said:
int arr[6];
std::cout<< arr;

The above outputs a memory address, whether you think this is an
offset embedded in machine code or it is stored in the XXXX segment is
quite irrellevant.
I tihnk you are speaking nonsense. It wouldn't be the first time.

Not to add too much or be drawn too far into this...

But - it prints an address because of the rule that a rvalue reference
to an array becomes the address of the first element of the array; which
has been mentioned before...

So, when the compiler evaluates the expression 'arr', as an operand
of the '<<' operator; it discovers an array name. The compiler applies
that rule, and produces an expression that is a pointer to the first
element of the array.

So.. the type of right-hand-side of '<<' (after this implicit
conversion) is
'int *', the value of the right-hand-side is the address of the first
element
of 'arr'.

Thus... the expression 'arr' is actually completely the same (in this
example)
as the expression '&arr[0]'.

That is , this statement:

std::cout<<arr;

is exactly the same as this statement:

std::cout<<(&arr[0]);

This is a subtle and important rule.

It even explains how array indexing is accomplished:

In this snippet:

int i; int array[10];

i = array[5];

when the compiler examines the expression 'array[5]'; it has
to implement the indexing operation in some fashion. Many compilers
simply follow the rule, so that 'array[5]' (internally in the compiler)
is actually expressed as:

(&array[0]) + 5;

If you think about it; this is also why indexing works "backwards",
that is:

[5]array

is a valid C expression that accesses the 5th element of the array.
Because 'array' is simply short-hand for (&array[0]). So,
the expression:

[5]array;

becomes:

5 + (&array[0]);


Note that the type of &array[0] is (in this example) an `int *'; so
that the expressions are simply pointer addition.

This is where people tend to confuse arrays and pointers; because
array indexing devolves into pointer addition.


But - that is preciesly why, in your std:: example, the result is
a memory address. The expression 'arr' is just "short hand" for (&arr[0]).

I think, if you apply this rule (which is in both the C and C++ standards)
things might become clearer.

Now - to the point of "there is some 'object' that holds this address."

Well, clearly the object has an address - however, there need not be
a separate object to "hold" that. The compiler can generate code that
calculates that address at runtime.

A simple example might help:

int i; int *ip;

ip = &i+1;

In this example, we have taken the address of 'i'. Does the compiler
need a separate 'object' to hold that address... well, not actually... but,
certainly it will calculate the address and use it in some fashion.

In fact, the compiler will compute the address of 'i', add the sizeof(int)
to that address and store the result in 'ip'. In the C/C++ sense, there
was never a 'container/object' that held the address of `i'; it was simply
calculated at runtime. There wasn't, necessarily, a separate 'container'
to hold the address of 'i'.

Having said that, just _how_ the compiler calculates &i might involve
runtime entities (not C++ 'objects')... for example, it may have to load
the address 'i' into a hardware register and add the sizeof(int) to it.

In that sense; the hardware register is the container that the generated
code employs to implement the expression... but, there's not a C++ "object"
for it... it's just how the expression is compiled.

I may be stepping into a quagmire here.. but, please consider this
simple rule.

When you see the name of an array in an expression, it is simply
"short-hand" for the address of the first element of the array.

I think ou can apply that rule and come to the understanding
of the intent of the C and C++ languages.

- Dave Rivers-
 
A

Alf P. Steinbach /Usenet

* Thomas David Rivers, on 25.05.2011 15:57:
Paul said:
int arr[6];
std::cout<< arr;

The above outputs a memory address, whether you think this is an offset
embedded in machine code or it is stored in the XXXX segment is quite
irrellevant.
I tihnk you are speaking nonsense. It wouldn't be the first time.
[snip]

That is , this statement:

std::cout<<arr;

is exactly the same as this statement:

std::cout<<(&arr[0]);

This is a subtle and important rule.


Note that (1) the above is true for the standard iostreams, but not in general
for other objects, and (2) Paul is a well-known troll, don't feed him.

[snip]

When you see the name of an array in an expression, it is simply
"short-hand" for the address of the first element of the array.

No, that's incorrect.

For example:

struct S
{
template< int n >
void operator<<( int (&)[n] )
{
cout << "Your array has " << n << " elements.\n";
}
};

int main()
{
int arr[6];
S stream;

stream << arr;
}


Cheers & hth.,

- Alf
 
P

Paul

Leigh Johnston said:
Leigh Johnston said:
On 25/05/2011 11:39, Paul wrote:
Asserting falsehoods just makes you look dense. The offset can be
"stored" in the text segment. R E A D A B O O K .


Its an object stored in memory regardless of what segment it is
stored in.


An offset is not an object; an offset can be embedded in the machine
code in the text segment where it is used to calculate the address of
an object when added to some other pointer such as a stack frame
pointer or a 'this' pointer.


int arr[6];
std::cout<< arr;

The above outputs a memory address, whether you think this is an offset
embedded in machine code or it is stored in the XXXX segment is quite
irrellevant.

Of course it is relevant; it is relevant to a discussion in which you
claim that an array identifier somehow "stores" a memory address which
is plainly absurd.
I'm obviously talking about an array type object , as described in the
C+ standards ref:

"[ Note: conversions affecting expressions of array type are described
in 4.2. Objects of array types cannot be modified, see 3.10. -end note ]"

We still do not understand your term "array-type object" and how this
differs from "array object". Stop using "Paul terms" if you are unable to
define what they mean. In the standard "array object" and "object of
array type" are synonyms.

An array type object is an object of an array type. That is a non modifiable
array type object.
An array object does not store a memory address to itself; implying it
does is absurd.
So what object stores this memory address?
Its even more absurd to suggest another object is created.
 
P

Paul

Thomas David Rivers said:
Paul said:
int arr[6];
std::cout<< arr;

The above outputs a memory address, whether you think this is an offset
embedded in machine code or it is stored in the XXXX segment is quite
irrellevant.
I tihnk you are speaking nonsense. It wouldn't be the first time.

Not to add too much or be drawn too far into this...

But - it prints an address because of the rule that a rvalue reference
to an array becomes the address of the first element of the array; which
has been mentioned before...

So, when the compiler evaluates the expression 'arr', as an operand
of the '<<' operator; it discovers an array name. The compiler applies
that rule, and produces an expression that is a pointer to the first
element of the array.
So.. the type of right-hand-side of '<<' (after this implicit conversion)
is
'int *', the value of the right-hand-side is the address of the first
element
of 'arr'.

Thus... the expression 'arr' is actually completely the same (in this
example)
as the expression '&arr[0]'.

That is , this statement:

std::cout<<arr;

is exactly the same as this statement:

std::cout<<(&arr[0]);

This is a subtle and important rule.

It even explains how array indexing is accomplished:

In this snippet:

int i; int array[10];

i = array[5];

when the compiler examines the expression 'array[5]'; it has
to implement the indexing operation in some fashion. Many compilers
simply follow the rule, so that 'array[5]' (internally in the compiler)
is actually expressed as:

(&array[0]) + 5;

If you think about it; this is also why indexing works "backwards",
that is:

[5]array

is a valid C expression that accesses the 5th element of the array.
Because 'array' is simply short-hand for (&array[0]). So,
the expression:

[5]array;

becomes:

5 + (&array[0]);


Note that the type of &array[0] is (in this example) an `int *'; so
that the expressions are simply pointer addition.

This is where people tend to confuse arrays and pointers; because
array indexing devolves into pointer addition.


But - that is preciesly why, in your std:: example, the result is
a memory address. The expression 'arr' is just "short hand" for
(&arr[0]).

I think, if you apply this rule (which is in both the C and C++ standards)
things might become clearer.

Now - to the point of "there is some 'object' that holds this address."

Well, clearly the object has an address - however, there need not be
a separate object to "hold" that. The compiler can generate code that
calculates that address at runtime.

No you have got something wrong here.
When code is executed at runtime it does not get compiled
A simple example might help:

int i; int *ip;

ip = &i+1;

In this example, we have taken the address of 'i'. Does the compiler
need a separate 'object' to hold that address... well, not actually...
but,
certainly it will calculate the address and use it in some fashion.

An array object is not the same as a single variable.

An array is a sequence of objects that cannot be addressed with a single
instruction, unless its size one or soemthing silly.
An object of array type is an object that strores the pointer to the array ,
for example arr in the following:

int arr[5];


output arr and you will find it has a pointer value.
examine arr with typeid and you will find it is an array type.
examine with sizeof and you get the size of the whole array
arr is a non modifiable object that decays in a pointer. The pointer
value(the address of the array) is stored someplace so that when the program
is exectued the location of an element can be accessed for example:


void foo(int* p){
p[2] = 6;
}


This function will correctly process 'arr' even though it may be compiled on
a different machine. You could write fucntion in asm or some other language
that supports pointers becuase an object of array type decays into a
pointer.

A compiler translates C++ code into object code.
In fact, the compiler will compute the address of 'i', add the sizeof(int)
to that address and store the result in 'ip'. In the C/C++ sense, there
was never a 'container/object' that held the address of `i'; it was simply
calculated at runtime. There wasn't, necessarily, a separate 'container'
to hold the address of 'i'.

Having said that, just _how_ the compiler calculates &i might involve
runtime entities (not C++ 'objects')... for example, it may have to load
the address 'i' into a hardware register and add the sizeof(int) to it.

In that sense; the hardware register is the container that the generated
code employs to implement the expression... but, there's not a C++
"object"
for it... it's just how the expression is compiled.
Got nothing to do with hardware registers really. Its more to do with
terminology and peoples understanding.
A non modifiable object of array type, is not the same thing as an array of
integer objects that this object references.
Although an array is not a pointer in C++. For the sake of this discussion
an array can be seen as basically a pointer tot he first element because in
most situations it decays into a pointer.


HTH Paul.
 

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

No members online now.

Forum statistics

Threads
473,781
Messages
2,569,615
Members
45,296
Latest member
HeikeHolli

Latest Threads

Top