Problem with array objects

T

Thomas David Rivers

Alf said:
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
Ah yes - you're correct....

I was over-simplifying... (neglecting templates and function-overloading
situations...) I should have said that I was speaking in more simple terms.
Basic C-like expressions...

And, I think, my assertion breaks down in the delete[] situation as well.

(Although, in your example, you didn't access the 'arr' array, only the
number of elements.... so, a twisted argument in the template situation
could be had... but, in truth, my "blanket" statement is clearly too
simple.)

I tend to lean more toward "C-isms" where the type is less involved in
distinguishing behavior.

I was also trying to motivate the idea of "pointer to first element".
Hopefully, my attempt to make that point isn't lost in the morass of
other issues.

- Dave Rivers -
 
P

Paul

Leigh Johnston said:
<snip>
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.

I repeat: nobody understands what you mean by "array type objects" being
different to "array objects"; stop using these terms as you are unable to
articulate what you mean by them.


You don't speak for everyone here.
If you don't understand what is meant by this then <shrug> what more can one
do to explain this.


Nobody except you is suggesting that. I have asserted that *no* memory
address is stored *at all*; there is only one object and that is the array
object itself; nothing stores its address as nothing needs to store its
address as its address can be *calculated* at runtime.
You are trying to suggest that some offset is stored in the text segment.

How can its address be calcualted at runtime?
Are you suggesting that an expression such as arr[2]; is converted to
address at runtime?
 
T

Thomas David Rivers

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


Well - this is likely a mistake.. but....

Let me say that appreciate your zeal in defending your understanding.

Let's start with some pretty basic principles.

First - to offer my credentials... I've actually implemented C and C++
compilers,
we have one of the premier offerings for the mainframe (z/Architecture)
system.
So, I speak with some authority (BTDT.)

In my discussions below, I am trying to be clear, but if I'm not, let
me apoligize
a-priori... if I am unclear, please feel free to ask...

So - to begin with some basic principles; let's remove the complications
of templates, function overloading, etc... and let's just talk
about some really simple/straight-forward examples and how things
actually work "under the covers" for those simple situations.
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];


Hmm... those sound like nice definitions... but, I think I would prefer
some simpler ones. I'm terribly confused by this "object of array type"
you have there, and why you would need one...

So - let me offer these...

Let's say that an array is a contiguous sequence of elements.
Arrays may be indexed, which results in a single element. (Let's not get
into multi-dimension issues for the moment; just one dimension.) An array
defines the number of elements it comprises, starting at element #0 and
continuing to n-1 elements.

Does that sound good?

If so - let's continue with this example:

int arr[5];

If we agree on the basic definition, then this would indicate that,
somewhere at runtime, there is a contiguous set of 5 'int' elements.
The name of that contigous set of elements is 'arr'.

Does that sound good?


So - then, expanding further... using our definition above, let's
consider this snippet:

int i;
int arr[5];

i = arr[4];

What are the basic semantics of that? I propose that would mean
to find the location of the array name 'arr', treat this as a pointer to
the first element of the array (per the rule), add to that starting
address 4*sizeof(int), to compute the address of the 4th element.
Dereference that point to access the `int' value located there,
then assign that `int' value to the variable 'i'.

Does that sound good/proper... is there something not right there?
(albeit, perhaps I'm a little loose, but I'm avoiding specifics like
'registers' and 'memory'.)

Now, let's consider this snippet:

int i;
int arr[5];

i = *((&arr[0]) + 4);

What does that statement do?

Following the indexing example we just walked thru, I propose
that it would mean, find the address of 'arr', treat it as a pointer to
the first element (per the rule), add 0*sizeof(int) to that pointer
to compute the address of the 0th element. Apply the '&' operator
which results in that same address. At this point, we have an (int *)
pointer to the 0th element. Add 4*sizeof(int) to it; which happens to
produce a pointer to the 4th element of the array. Apply the '*' operator
to dereference that point, which produces an `int' that is the 4th
element of the array. Assign that value to `i'.

Does that sound right?

I believe that would show, in this basic situation; the equivalence
of the two statements.

If you agree with that; then we have a very simple answer to this
statement:

output arr and you will find it has a pointer value.


Yes! That is true (again, neglecting templates and other more complicated
type situations.) I think, the reason it is true is because the
expression 'arr'
becomes a pointer to the first element of the array... hence, it,
definitionally
is a pointer value.
examine arr with typeid and you will find it is an array type.


OK - at this point - let's bring typeid back into the picture.

You are correct; it _is_ an array type... so - why does typeid() not say
it's a pointer??? I just got thru explaining why it would be a pointer,
but typeid() says it's not! What's going on?

This is because of the semantics of typeid(). My statements/rationing
above was discussing accessing the array... not examining its type.
typeid() only looks at the type... the type of 'arr' is the contigous set
of 5 elements... recall that typeid() doesn't evaluate the expression, it
evaluates the type of the expression... it's an important distinction.
examine with sizeof and you get the size of the whole array


The reason for this is the same as typeid(), sizeof() deals in the type
of the expression - it does not evaluate it.
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:


I'm not sure about the 'non-modifiable' part of that...

Clearly though, when you say "the pointer value.. is stored
someplace"... that is
frequently true... in this example:
void foo(int* p){
p[2] = 6;
}

If foo() were invoked with 'arr' as a parameter; then the address of
'arr' must
be stored somewhere... it's clearly stored in 'p'.

However, I believe the question really is "is it stored somewhere
else?" That is,
is there another "object" that contains the address of 'arr'.. and the
value
of the other object would be passed to foo()?

I think the answer is "well, you _could_ do it that way - but - it's
frequently
not needed."

Let's consider this for example:

int *ip;
int arr[5];

ip = arr;
foo(ip);

Would you say that would be equivalent to:

int arr[5];

foo(arr);

If so, then in the first case, clearly the pointer to the first element
of `arr'
has been saved in the "object" named `ip'. That value is then passed
as a parameter to foo().

In the second case, is there some mysterious unnamed "object" which
contains the address of the first element of `arr', and the value
of the unnamed "object" is then passed as a parameter to foo()?

Well - as an implementation detail; you _could_ do that... but it is more
likely that the compiler can generate code that computes the address
of `arr' and simply passes that computed value as the parameter to foo()?

Thus, if my assertion is correct the expression:

foo(arr)

actually can be thought to be equivalent to

foo((&arr[0]))

(again, neglecting templates/function-overloading, etc... let's keep it
simple.)

The second expression simply makes the underlying semantics obvious.


Got nothing to do with hardware registers really. Its more to do with
terminology and peoples understanding.


You are correct - I was using 'registers' as a term that I was hoping would
make things clear; I hope the discussion above (which avoids that) is more
in-line with what you are looking for.
A non modifiable object of array type, is not the same thing as an
array of integer objects that this object references.

I'm having problems with this sentence.. when you say "A non
modifiable object
of array type"; do you mean a `const' array ? I'm not sure I
understand what you're
getting at there...

Are you saying there exists this unnamed "object" that contains the
pointer to
array?
Although an array is not a pointer in C++. For the sake of this
discussion an array can be seen as basically a pointer to the first
element because in most situations it decays into a pointer.


I think this is an oversimplication; as you point out above... If we
agree
that an array is a contiguous set of elements, then that's what it is...

We then say that there is this added rule that when the array name is
referenced
in an expression, the result of that expression is a pointer to the
first element...

With those two, one can readily define the []-operator in a consistent
fashion
vis-a-vis pointer addition.

That is (and, again, this is neglecting templates/function-overloading,
etc...)
given these declarations:

int i;
int arr[5];

the statements:

i = arr[4];

and

i = *((&arr[0])+4);

are completely equivalent.

If we can agree on those definitions and these basic semantics, then we can
proceed to talk about the slightly-more-complicated issues, in particular,
how do you handle multiple dimensions, and what does "&arr" mean?

However, one step at a time.

- Dave Rivers -
 
P

Paul

A. Bolmarcich said:
[snip]
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.

The situation with the unary * and unary & operators is the same for
an array and for a non-array. The C++ standard does not specify
different behaviors depending on whether the operand of the unary *
and unary & operators is an array or non-array.

Here is the paragraph from the C++ standard about the unary *
operator.

The unary * operator performs indirection: the expression to which
it is applied shall be a pointer to an object type, or a pointer to
a function type and the result is an lvalue referring to the object
or function to which the expression points. If the type of the
expression is "pointer to T", the type of the result is "T".
[Note: a pointer to an incomplete type (other than cv void ) can be
dereferenced. The lvalue thus obtained can be used in limited ways
(to initialize a reference, for example); this lvalue must not be
converted to an rvalue, see 4.1. ]

The C++ standard does not specify different behaviors for an array
and a non-array with the unary * operator.

Here is the paragraph from the C++ standard about the unary &
operator.

The result of the unary & operator is a pointer to its operand.
The operand shall be an lvalue or a qualified-id. In the first
case, if the type of the expression is "T", the type of the result
is "pointer to T". In particular, the address of an object of type
"cv T" is "pointer to cv T", with the same cv-qualifiers. For a
qualified-id, if the member is a static member of type "T", the
type of the result is plain "pointer to T". If the member is
a nonstatic member of class C of type T, the type of the result is
"pointer to member of class C of type T." [Example:

struct A { int i; };
struct B : A { };
... &B::i ... // has type int A::*

--end example] [Note: a pointer to member formed from a mutable
nonstatic data member (7.1.1) does not reflect the mutable
specifier associated with the nonstatic data member. ]

The C++ standard does not specify different behaviors for an array
and a non-array with the unary & operator.

A difference with array and non-array results is that
array-to-pointer conversion is applied to an array result.

In your example, the statement

int* parr = arr;

implicitly applies array-to-pointer conversion to the array result of
the expression arr. The result of that conversion is a pointer to
the first element of arr, not a pointer to arr. Because parr is a
pointer to int, the result of dereferencing it is an int.

In your example, the statement

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

initializes pparr with a pointer to arr, not a pointer to an element
of arr. Because pparr is a pointer to an array of int, the result of
dereferencing it is an array of int. Array-to-pointer conversion is
implicitly applied to that result and the result of the conversion
is a pointer to int that points to the first element of arr.
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.

The result of using the identifier 'arr' in an expression is an
array. An array is a single object that contains sub-objects. The
expression &arr points to the object that is the array named arr.
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?

Having the value of a pointer be the null pointer is valid. The
effect of dereferencing the null pointer is undefined.
An array object must store a pointer otherwise how does it know, where in
memory, the array is?
The post you have replied to up till here was not a post by me.
I believe the following is addressed toward sme.
In a previous post you asked: "So where does the memory address value
come from? Its not stored in the array of integer objects." My
answer was (see
http://groups.google.com/group/comp.lang.c++/msg/90a32f760cdfc958?hl=en)

Where the memory address comes from depends on where the
implementation decides to store the array. For example, an object
with automatic storage duration, such a non-static array declared
in a function, is allocated on the stack in an implementation that
uses a stack for automatic storage.

The compiler knows the compile-time constant offset in the stack
frame where it has decided to store the array. In places where a
program needs the memory address of the array, the compiler puts
in instructions to sum that compile-time constant offset and the
current value of the stack pointer.

In the last sentence, "stack pointer" should have been "stack
frame pointer".

For the program

void foo() {
int arr[4], (*pparr)[4];

pparr = &arr;
}

the assembler output of the GNU C++ compiler for the assignment
statement for an i686 system is

leal -20(%ebp), %eax
movl %eax, -4(%ebp)

This is a very tiny piece of code and the compiler is allowed to optimise
this .
Look at some asm code where an array is passed to a function and you will
see what the value pushed onto the stack is.
Here is a simple program:

void foo(int* p){ p[0]=7;}

int main(){
int arr[5]={0};
foo(arr);
}

And here is the asm output:

; Listing generated by Microsoft (R) Optimizing Compiler Version
14.00.50727.762

TITLE C:\cpp\public.cpp
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC ?foo@@YAXPAH@Z ; foo
; Function compile flags: /Odtp
_TEXT SEGMENT
_p$ = 8 ; size = 4
?foo@@YAXPAH@Z PROC ; foo
; File c:\cpp\public.cpp
; Line 3
push ebp
mov ebp, esp
; Line 4
mov eax, DWORD PTR _p$[ebp]
mov DWORD PTR [eax], 7
; Line 5
pop ebp
ret 0
?foo@@YAXPAH@Z ENDP ; foo
_TEXT ENDS
PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
/*************************************/
_arr$ = -20 ; size = 20

/************************************/
The above line is the array type object.
This is a pointer in asm because array type objects do not exist in asm.
/************************************/
_main PROC
; Line 7
push ebp
mov ebp, esp
sub esp, 20 ; 00000014H
; Line 8
mov DWORD PTR _arr$[ebp], 0
xor eax, eax
mov DWORD PTR _arr$[ebp+4], eax
mov DWORD PTR _arr$[ebp+8], eax
mov DWORD PTR _arr$[ebp+12], eax
mov DWORD PTR _arr$[ebp+16], eax
; Line 9
/**************************************/
lea ecx, DWORD PTR _arr$[ebp]
push ecx
/*************************************/
The above two lines push the address of the arrays first element onto the
stack prior to invokation of foo.
/*************************************/
call ?foo@@YAXPAH@Z ; foo
add esp, 4
; Line 11
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END


In the above asm listing arr is _arr$ , that is a pointer object that has
the value of -20.

The compiler has allocated arr at offset -20 in the stack frame and
pparr at offset -4 in the stack frame. The assembler instructions
store in pparr the sum of -20 and the stack frame address.
Determining the address of arr did not use a value stored in an
object.
You example was so simple that the compiler has optimised the array object
into a temporary literal (-20).

[snip]
No the C++ standard states its an array type object.

The object pointed to is an array TYPE.

That's right, pparr points to an array type object, an object that
stores an array (the one named arr, in this case). pparr does not
point to an object that stores the address of an array.

As shown in the asm listing _arr$ is an object with a value of -20. This is
a pointer object that points to the first element of the array, this object
stores the address of the array.

In C++ this object is not considered a pointer , it is an array type object.
The C++ standards refers to it as a non modifiable object of array type.
 
P

Paul

Leigh Johnston said:
Leigh Johnston said:
On 25/05/2011 16:36, Paul wrote:
<snip>
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.

I repeat: nobody understands what you mean by "array type objects"
being different to "array objects"; stop using these terms as you are
unable to articulate what you mean by them.


You don't speak for everyone here.

Nevertheless what I said is correct.
If you don't understand what is meant by this then <shrug> what more can
one do to explain this.

Nobody understands what *you* mean by these vague terms of *yours* as
*you* have failed to define them clearly.

Well the authors of the C++ seem to understand it, why do they use the same
terms?
I requote:
"[ Note: conversions affecting expressions of array type are described in
4.2. Objects of array types cannot be modified, see 3.10. -end note ]"

So what is it you find vague about objects of array types?
Or do you think there is a difference between me saying an "array type
object" and an "object of array type"?


<snip>
 
P

Paul

Thomas David Rivers said:
Well - this is likely a mistake.. but....

Let me say that appreciate your zeal in defending your understanding.

Let's start with some pretty basic principles.

First - to offer my credentials... I've actually implemented C and C++
compilers,
we have one of the premier offerings for the mainframe (z/Architecture)
system.
So, I speak with some authority (BTDT.)

In my discussions below, I am trying to be clear, but if I'm not, let me
apoligize
a-priori... if I am unclear, please feel free to ask...

So - to begin with some basic principles; let's remove the complications
of templates, function overloading, etc... and let's just talk
about some really simple/straight-forward examples and how things
actually work "under the covers" for those simple situations.
So basically you want to consider an array as a simple pointer.
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];


Hmm... those sound like nice definitions... but, I think I would prefer
some simpler ones. I'm terribly confused by this "object of array type"
you have there, and why you would need one...

Hold on lets clear this confusion up.
In asm an array is basically a pointer, in C++ its an object of array type
(which I see as a non modifiable pointer with added typeinfo).

So according to C++ with the deifnition:
int arr[5];

The object arr is not a pointer , it is a non modifiable object of array
type.
If you want to forget about all the typeinfo etc and simply regard this as a
pointer for the sake of the dscussion I can go with that.


So - let me offer these...

Let's say that an array is a contiguous sequence of elements.

Aha now you are shifting the focus, to the actual objects of the array. Lets
be clear about these two definintions of array.
We have an array of 5 ints like so:
[int][int][int][int][int]

To access this array we need to have a pointer so we have:
[ptr_arr]...................[int][int][int][int][int]

The term array can be applied to a contiguous sequence of integer objects or
to the identifier(pointer) for these objects.
Going back to the old arr , arr is a pointer object that points to the
sequence of integer objects. This is a different object from any of the five
integer objects
1) An array is a pointer such as arr.
2) An array is a sequence of objects.
Note: Assuming we're agreeing to use this "pointer" terminology instead of
the C++ "object of array type" terminology.

Arrays may be indexed, which results in a single element. (Let's not get
into multi-dimension issues for the moment; just one dimension.) An array
defines the number of elements it comprises, starting at element #0 and
continuing to n-1 elements.

Does that sound good?

If so - let's continue with this example:

int arr[5];

If we agree on the basic definition, then this would indicate that,
somewhere at runtime, there is a contiguous set of 5 'int' elements.
The name of that contigous set of elements is 'arr'.

Does that sound good?

No because arr is the name of a pointer object that points to the array of 5
ints.

You could consider it the name of the array of integer objects , ofc, but I
dont think it is suitable to ignore that pointer object named arr as this
seems to be what the discussion is all about.

So - then, expanding further... using our definition above, let's
consider this snippet:
Well I didnt agree with your definition above :)
int i;
int arr[5];

i = arr[4];

What are the basic semantics of that? I propose that would mean
to find the location of the array name 'arr', treat this as a pointer to
the first element of the array (per the rule), add to that starting
address 4*sizeof(int), to compute the address of the 4th element.
Dereference that point to access the `int' value located there,
then assign that `int' value to the variable 'i'.

Does that sound good/proper... is there something not right there?
(albeit, perhaps I'm a little loose, but I'm avoiding specifics like
'registers' and 'memory'.)

Now, let's consider this snippet:

int i;
int arr[5];

i = *((&arr[0]) + 4);

What does that statement do?

Following the indexing example we just walked thru, I propose
that it would mean, find the address of 'arr', treat it as a pointer to
the first element (per the rule), add 0*sizeof(int) to that pointer
to compute the address of the 0th element. Apply the '&' operator
which results in that same address. At this point, we have an (int *)
pointer to the 0th element. Add 4*sizeof(int) to it; which happens to
produce a pointer to the 4th element of the array. Apply the '*' operator
to dereference that point, which produces an `int' that is the 4th
element of the array. Assign that value to `i'.

Does that sound right?

I believe that would show, in this basic situation; the equivalence
of the two statements.

If you agree with that; then we have a very simple answer to this
statement:

output arr and you will find it has a pointer value.


Yes! That is true (again, neglecting templates and other more
complicated
type situations.) I think, the reason it is true is because the
expression 'arr'
becomes a pointer to the first element of the array... hence, it,
definitionally
is a pointer value.
examine arr with typeid and you will find it is an array type.


OK - at this point - let's bring typeid back into the picture.

You are correct; it _is_ an array type... so - why does typeid() not say
it's a pointer??? I just got thru explaining why it would be a pointer,
but typeid() says it's not! What's going on?

This is because of the semantics of typeid(). My statements/rationing
above was discussing accessing the array... not examining its type.
typeid() only looks at the type... the type of 'arr' is the contigous
set
of 5 elements... recall that typeid() doesn't evaluate the expression, it
evaluates the type of the expression... it's an important distinction.
examine with sizeof and you get the size of the whole array


The reason for this is the same as typeid(), sizeof() deals in the type
of the expression - it does not evaluate it.
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:


I'm not sure about the 'non-modifiable' part of that...

Clearly though, when you say "the pointer value.. is stored someplace"...
that is
frequently true... in this example:
void foo(int* p){
p[2] = 6;
}

If foo() were invoked with 'arr' as a parameter; then the address of 'arr'
must
be stored somewhere... it's clearly stored in 'p'.

However, I believe the question really is "is it stored somewhere else?"
That is,
is there another "object" that contains the address of 'arr'.. and the
value
of the other object would be passed to foo()?

I think the answer is "well, you _could_ do it that way - but - it's
frequently
not needed."

Let's consider this for example:

int *ip;
int arr[5];

ip = arr;
foo(ip);

Would you say that would be equivalent to:

int arr[5];

foo(arr);

If so, then in the first case, clearly the pointer to the first element of
`arr'
has been saved in the "object" named `ip'. That value is then passed
as a parameter to foo().

In the second case, is there some mysterious unnamed "object" which
contains the address of the first element of `arr', and the value
of the unnamed "object" is then passed as a parameter to foo()?

Well - as an implementation detail; you _could_ do that... but it is more
likely that the compiler can generate code that computes the address
of `arr' and simply passes that computed value as the parameter to foo()?

Thus, if my assertion is correct the expression:

foo(arr)

actually can be thought to be equivalent to

foo((&arr[0]))

(again, neglecting templates/function-overloading, etc... let's keep it
simple.)

The second expression simply makes the underlying semantics obvious.


Got nothing to do with hardware registers really. Its more to do with
terminology and peoples understanding.


You are correct - I was using 'registers' as a term that I was hoping
would
make things clear; I hope the discussion above (which avoids that) is
more
in-line with what you are looking for.
A non modifiable object of array type, is not the same thing as an array
of integer objects that this object references.

I'm having problems with this sentence.. when you say "A non modifiable
object
of array type"; do you mean a `const' array ? I'm not sure I understand
what you're
getting at there...

Are you saying there exists this unnamed "object" that contains the
pointer to
array?

No arr is a pointer to the array.
But as I explained above , in C++ it is not simple pointer it is a non
modifiable pointer with additional type info. This is an object of array
type.


Although an array is not a pointer in C++. For the sake of this
discussion an array can be seen as basically a pointer to the first
element because in most situations it decays into a pointer.


I think this is an oversimplication; as you point out above... If we
agree
that an array is a contiguous set of elements, then that's what it is...

We then say that there is this added rule that when the array name is
referenced
in an expression, the result of that expression is a pointer to the first
element...

With those two, one can readily define the []-operator in a consistent
fashion
vis-a-vis pointer addition.

That is (and, again, this is neglecting templates/function-overloading,
etc...)
given these declarations:

int i;
int arr[5];

the statements:

i = arr[4];

and

i = *((&arr[0])+4);

are completely equivalent.

If we can agree on those definitions and these basic semantics, then we
can
proceed to talk about the slightly-more-complicated issues, in particular,
how do you handle multiple dimensions, and what does "&arr" mean?

However, one step at a time.

- Dave Rivers -
Some things I agree with you and others I do not, If we can aggree to
consider arr as a pointer and ignore all the typeinfo then thats ok , but
you must also agree with me that arr is a pointer object under the hood and
not simply a name for the array of integer objects.
 
I

Ian Collins

This is a very tiny piece of code and the compiler is allowed to optimise
this .
Look at some asm code where an array is passed to a function and you will
see what the value pushed onto the stack is.
Here is a simple program:

void foo(int* p){ p[0]=7;}

int main(){
int arr[5]={0};
foo(arr);
}

And here is the asm output:

; Listing generated by Microsoft (R) Optimizing Compiler Version
14.00.50727.762

TITLE C:\cpp\public.cpp
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC ?foo@@YAXPAH@Z ; foo
; Function compile flags: /Odtp
_TEXT SEGMENT
_p$ = 8 ; size = 4
?foo@@YAXPAH@Z PROC ; foo
; File c:\cpp\public.cpp
; Line 3
push ebp
mov ebp, esp
; Line 4
mov eax, DWORD PTR _p$[ebp]
mov DWORD PTR [eax], 7
; Line 5
pop ebp
ret 0
?foo@@YAXPAH@Z ENDP ; foo
_TEXT ENDS
PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
/*************************************/
_arr$ = -20 ; size = 20

/************************************/
The above line is the array type object.

That's where you are very, very wrong. _arr$ is a constant with the
value -20. The MASM term is a "Manifest Constant", look it up.
 
T

Thomas David Rivers

Paul said:
So basically you want to consider an array as a simple pointer.


No - not at all - I provided my suggested definition of the term 'array'.

Basically, in that, an 'array' is a contiguous set of elements with
a defined length, where each element can be accessed individually.
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];



Hmm... those sound like nice definitions... but, I think I would prefer
some simpler ones. I'm terribly confused by this "object of array
type"
you have there, and why you would need one...


Hold on lets clear this confusion up.
In asm an array is basically a pointer, in C++ its an object of array
type (which I see as a non modifiable pointer with added typeinfo).


Actually, in 'asm' - an array is a contiguous set of elements of the
same type.
The concept does not change because the implementation language changes.
The array remains a contiguous set of elements of the same type.
Certainly, in 'asm', it might be convenient to have a pointer to that
allocated memory,
but the array is still the entire set of elements. Nothing more,
nothing less.

That is, a pointer is a pointer, an array is an array.

In C/C++, there is not this 'object of array type' you mention, there
is the idea
of an 'array'. An array is simply a contiguous set of elements of the same
type, each element can be accessed. When the array is allocated, all
of the
memory required for the entire set is allocated. When the array is
deallocated,
the entire array "goes away".

Let's just back up and start with that simple idea; then we can proceed
from there and build up the ideas of accessing the array and/or accessing
elements of the array.

So - to reiterate...

An array is simply a contigous set of like-typed elements.

How does that sound for a start?

I've added some more comments below - just to clarify a little. However,
we really need to agree on this definition... then, I think we can build
up from there and hopefully clarify this a little.
So according to C++ with the deifnition:
int arr[5];

The object arr is not a pointer , it is a non modifiable object of
array type.
If you want to forget about all the typeinfo etc and simply regard
this as a pointer for the sake of the dscussion I can go with that.
No, I don't think so.. the object 'arr' is not a pointer - it is a
contiguous
set of 5 elements of type 'int'.

Note that I keep using the word 'element'... arrays have elements (just
like
structures have members, for instance.) This will be important later.
So - let me offer these...

Let's say that an array is a contiguous sequence of elements.


Aha now you are shifting the focus, to the actual objects of the
array. Lets be clear about these two definintions of array.
We have an array of 5 ints like so:
[int][int][int][int][int]

To access this array we need to have a pointer so we have:
[ptr_arr]...................[int][int][int][int][int]


Actually - if you will follow along with me and we can agree on some
really basic ideas, then it will just so happen that multi-dimensional
arrays "just work", without these other pointers you are suggestion.

Because of that, I'd like to defer the discussion of multi-dimensional
arrays until we can get to the basic understanding of C/C++ simple
arrays. If you don't mind...
The term array can be applied to a contiguous sequence of integer
objects or to the identifier(pointer) for these objects.

Actually - that's not what I provided in my definition. The term
'array' simply
means the entire set of the contiguous elements; nothing more, nothing less.

It's important to understand that there is no separate pointer to the
objects,
there is simply the entire set of objects.

There is a context in which a reference to the entire set of objects is
converted
to a pointer to the first element... but that is different. It is not a
separate object
that contains the address.

That might be a good idea, and I mention at least one other language that
does take that approach below.. but, it's simply not how C/C++ is defined.
Going back to the old arr , arr is a pointer object that points to the
sequence of integer objects. This is a different object from any of
the five integer objects
1) An array is a pointer such as arr.
2) An array is a sequence of objects.
Note: Assuming we're agreeing to use this "pointer" terminology
instead of the C++ "object of array type" terminology.


I don't think so... an array is not a pointer. An array is a contiguous
set of elements
of the same type. In some situations, references to this set are
converted to
the address of the first element of the set.

That really is all there is to it.
Arrays may be indexed, which results in a single element. (Let's not
get
into multi-dimension issues for the moment; just one dimension.) An
array
defines the number of elements it comprises, starting at element #0 and
continuing to n-1 elements.

Does that sound good?

If so - let's continue with this example:

int arr[5];

If we agree on the basic definition, then this would indicate that,
somewhere at runtime, there is a contiguous set of 5 'int' elements.
The name of that contigous set of elements is 'arr'.

Does that sound good?


No because arr is the name of a pointer object that points to the
array of 5 ints.


Actually - no, 'arr' is the name of the start of the contiguous set of 5
int elements.

That's all 'arr' is - nothing more, nothing less. However, in some
situations, the reference
to the set of elements is converted to the address of the first element.

'arr' is not a pointer to another location. It is the actual location
of the 5 ints.
You could consider it the name of the array of integer objects , ofc,
but I dont think it is suitable to ignore that pointer object named
arr as this seems to be what the discussion is all about.


I was trying to get to the idea that there is no "pointer object named
arr". There
actually is not one of those.

'arr' is the name of the contiguous set of 5 int elements.

It is not a pointer to the 5 int elements; it actually is the 5 int
elements.

When you use the name 'arr' in expression contexts where the value is
required,
the 'decay' as you put it occurs, and the result of that expression is a
pointer
to the first element of the array.

This is the subtle point...

Thus, in the snippet:

int *ip;
int arr[5];

ip = arr;

what happens semantically? In this statement above, the name 'arr' is used
in an expression that requires its value. In that case, the semantics
indicate
that the result of the expression would be the address of the first element.

Thus; these two statements are completely, totally, and utterly (in the
context of the declarations above) identical:

ip = arr;

ip = (&arr[0]);

They are identical in every aspect; because of the rule that an array name
used in an expression context is treated as the address of the first
element.

This is the definition of C/C++. This is really how it works. There
is not other
'magic' behind it.. no other objects-pointing-to-objects or anything else.

That's all there is to this... nothing more... There does not exist a
separate
object that points to the 5 bytes...

Unfortunately - this is not a matter to be debated. This just happens to be
the way C and C++ are defined. Other languages (e.g. PL/I) use approaches
similar to what you are considering.. it's called a "dope vector" and can be
very helpful.. but, that's not how C and C++ are defined.

Again, there is not a "pointer object" that points to the array; there is
only the array. And, an array is not a pointer... however, in some
situations,
the name of the array does not indicate the array in-total, but refers to
the address of the first element.

I'm afraid that's not really open to discussion - it simply is true by
definition.
It really, actually, truly is the way it works and the way its defined.

Now - I realize others have tried to explain this - I was hoping to add
clarification
to that. Starting with some really basic definitions and "working up"
from there.

But - we have to agree that an array is the contiguous set of elements
of the
same type. That there is nothing more to it.

If it is something about which you disagree, then I'll have give up on
the tutorial.
Which would be a shame, because it's really kinda cool how it all works out.

- Dave Rivers -
 
P

Paul

Leigh Johnston said:
<snip>
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.

I repeat: nobody understands what you mean by "array type objects"
being different to "array objects"; stop using these terms as you are
unable to articulate what you mean by them.


You don't speak for everyone here.

Nevertheless what I said is correct.

If you don't understand what is meant by this then <shrug> what more
can
one do to explain this.

Nobody understands what *you* mean by these vague terms of *yours* as
*you* have failed to define them clearly.

Well the authors of the C++ seem to understand it, why do they use the
same terms?

I have already said the terms in the standard are synonyms whereas your
terms are apparently not synonyms but have special distinct meanings that
only you seem to understand.
I requote:
"[ Note: conversions affecting expressions of array type are described
in 4.2. Objects of array types cannot be modified, see 3.10. -end note ]"

"array object" and "object of array type" are synonyms (the same thing).
So what is it you find vague about objects of array types?
Or do you think there is a difference between me saying an "array type
object" and an "object of array type"?

Nobody but *you* understands the difference between how *you* define these
terms of *yours*.
You are obviously to thick to understand even though It has been explained
to you.
 
P

Paul

Thomas David Rivers said:
No - not at all - I provided my suggested definition of the term 'array'.

Basically, in that, an 'array' is a contiguous set of elements with
a defined length, where each element can be accessed individually.
Oh right I though I was aggreing with you on your terms but it seems that
whether I discuss an array in one context you will discuss it in another
context.

I think and array is a contiguious sequence of elements but I can also
accept that an array identifier is called an array and that idntifier is a
non modifiable object.
If I talk about an array in the context of an indentifier or in the context
of a sequence of objects you will change the correct and say I am wrong.


An array is a contiguous sequence of objects and nothing more.
So no point in going any further .


<snip>
 
P

Paul

Leigh Johnston said:
A. Bolmarcich said:
[snip]
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.

The situation with the unary * and unary & operators is the same for
an array and for a non-array. The C++ standard does not specify
different behaviors depending on whether the operand of the unary *
and unary & operators is an array or non-array.

Here is the paragraph from the C++ standard about the unary *
operator.

The unary * operator performs indirection: the expression to which
it is applied shall be a pointer to an object type, or a pointer to
a function type and the result is an lvalue referring to the object
or function to which the expression points. If the type of the
expression is "pointer to T", the type of the result is "T".
[Note: a pointer to an incomplete type (other than cv void ) can be
dereferenced. The lvalue thus obtained can be used in limited ways
(to initialize a reference, for example); this lvalue must not be
converted to an rvalue, see 4.1. ]

The C++ standard does not specify different behaviors for an array
and a non-array with the unary * operator.

Here is the paragraph from the C++ standard about the unary &
operator.

The result of the unary & operator is a pointer to its operand.
The operand shall be an lvalue or a qualified-id. In the first
case, if the type of the expression is "T", the type of the result
is "pointer to T". In particular, the address of an object of type
"cv T" is "pointer to cv T", with the same cv-qualifiers. For a
qualified-id, if the member is a static member of type "T", the
type of the result is plain "pointer to T". If the member is
a nonstatic member of class C of type T, the type of the result is
"pointer to member of class C of type T." [Example:

struct A { int i; };
struct B : A { };
... &B::i ... // has type int A::*

--end example] [Note: a pointer to member formed from a mutable
nonstatic data member (7.1.1) does not reflect the mutable
specifier associated with the nonstatic data member. ]

The C++ standard does not specify different behaviors for an array
and a non-array with the unary & operator.

A difference with array and non-array results is that
array-to-pointer conversion is applied to an array result.

In your example, the statement

int* parr = arr;

implicitly applies array-to-pointer conversion to the array result of
the expression arr. The result of that conversion is a pointer to
the first element of arr, not a pointer to arr. Because parr is a
pointer to int, the result of dereferencing it is an int.

In your example, the statement

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

initializes pparr with a pointer to arr, not a pointer to an element
of arr. Because pparr is a pointer to an array of int, the result of
dereferencing it is an array of int. Array-to-pointer conversion is
implicitly applied to that result and the result of the conversion
is a pointer to int that points to the first element of arr.

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.

The result of using the identifier 'arr' in an expression is an
array. An array is a single object that contains sub-objects. The
expression &arr points to the object that is the array named arr.

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?

Having the value of a pointer be the null pointer is valid. The
effect of dereferencing the null pointer is undefined.

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?
The post you have replied to up till here was not a post by me.
I believe the following is addressed toward sme.
In a previous post you asked: "So where does the memory address value
come from? Its not stored in the array of integer objects." My
answer was (see
http://groups.google.com/group/comp.lang.c++/msg/90a32f760cdfc958?hl=en)

Where the memory address comes from depends on where the
implementation decides to store the array. For example, an object
with automatic storage duration, such a non-static array declared
in a function, is allocated on the stack in an implementation that
uses a stack for automatic storage.

The compiler knows the compile-time constant offset in the stack
frame where it has decided to store the array. In places where a
program needs the memory address of the array, the compiler puts
in instructions to sum that compile-time constant offset and the
current value of the stack pointer.

In the last sentence, "stack pointer" should have been "stack
frame pointer".

For the program

void foo() {
int arr[4], (*pparr)[4];

pparr = &arr;
}

the assembler output of the GNU C++ compiler for the assignment
statement for an i686 system is

leal -20(%ebp), %eax
movl %eax, -4(%ebp)

This is a very tiny piece of code and the compiler is allowed to
optimise this .
Look at some asm code where an array is passed to a function and you
will see what the value pushed onto the stack is.
Here is a simple program:

void foo(int* p){ p[0]=7;}

int main(){
int arr[5]={0};
foo(arr);
}

And here is the asm output:

; Listing generated by Microsoft (R) Optimizing Compiler Version
14.00.50727.762

TITLE C:\cpp\public.cpp
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC ?foo@@YAXPAH@Z ; foo
; Function compile flags: /Odtp
_TEXT SEGMENT
_p$ = 8 ; size = 4
?foo@@YAXPAH@Z PROC ; foo
; File c:\cpp\public.cpp
; Line 3
push ebp
mov ebp, esp
; Line 4
mov eax, DWORD PTR _p$[ebp]
mov DWORD PTR [eax], 7
; Line 5
pop ebp
ret 0
?foo@@YAXPAH@Z ENDP ; foo
_TEXT ENDS
PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
/*************************************/
_arr$ = -20 ; size = 20

/************************************/
The above line is the array type object.
This is a pointer in asm because array type objects do not exist in asm.
/************************************/
_main PROC
; Line 7
push ebp
mov ebp, esp
sub esp, 20 ; 00000014H
; Line 8
mov DWORD PTR _arr$[ebp], 0
xor eax, eax
mov DWORD PTR _arr$[ebp+4], eax
mov DWORD PTR _arr$[ebp+8], eax
mov DWORD PTR _arr$[ebp+12], eax
mov DWORD PTR _arr$[ebp+16], eax
; Line 9
/**************************************/
lea ecx, DWORD PTR _arr$[ebp]
push ecx
/*************************************/
The above two lines push the address of the arrays first element onto
the stack prior to invokation of foo.
/*************************************/
call ?foo@@YAXPAH@Z ; foo
add esp, 4
; Line 11
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END


In the above asm listing arr is _arr$ , that is a pointer object that
has the value of -20.

It is not a pointer object; it is a constant.
No Leigh it's a pointer.

Funny sense of Deja vu here.
 
P

Paul

Ian Collins said:
This is a very tiny piece of code and the compiler is allowed to optimise
this .
Look at some asm code where an array is passed to a function and you will
see what the value pushed onto the stack is.
Here is a simple program:

void foo(int* p){ p[0]=7;}

int main(){
int arr[5]={0};
foo(arr);
}

And here is the asm output:

; Listing generated by Microsoft (R) Optimizing Compiler Version
14.00.50727.762

TITLE C:\cpp\public.cpp
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC ?foo@@YAXPAH@Z ; foo
; Function compile flags: /Odtp
_TEXT SEGMENT
_p$ = 8 ; size = 4
?foo@@YAXPAH@Z PROC ; foo
; File c:\cpp\public.cpp
; Line 3
push ebp
mov ebp, esp
; Line 4
mov eax, DWORD PTR _p$[ebp]
mov DWORD PTR [eax], 7
; Line 5
pop ebp
ret 0
?foo@@YAXPAH@Z ENDP ; foo
_TEXT ENDS
PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
/*************************************/
_arr$ = -20 ; size = 20

/************************************/
The above line is the array type object.

That's where you are very, very wrong. _arr$ is a constant with the
value -20. The MASM term is a "Manifest Constant", look it up.
No _arr$ is a pointer.
Constantness is a term that defines whether it's modifiable or not. It may
be a constant pointer.
WTF is Manifest constant , and you accuse me of using terminology nobody
understands. Thats utter bullshit _arr$ is a pointer the same as px is a
pointer in the following:

int main(){
int x=5;
int* px= &x;
}

PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
_px$ = -8 ; size = 4
_x$ = -4 ; size = 4
_main PROC
; File c:\cpp\public.cpp
; Line 5
push ebp
mov ebp, esp
sub esp, 8
; Line 6
mov DWORD PTR _x$[ebp], 5
; Line 7
lea eax, DWORD PTR _x$[ebp]
mov DWORD PTR _px$[ebp], eax
; Line 8
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END
 
I

Ian Collins

No _arr$ is a pointer.
Constantness is a term that defines whether it's modifiable or not. It may
be a constant pointer.

No, it is a constant value. How much x86 assembly programming have you
actually done? Not a lot I'd guess.
WTF is Manifest constant , and you accuse me of using terminology nobody
understands. Thats utter bullshit _arr$ is a pointer the same as px is a
pointer in the following:

Did you (I sometimes doubt if you are capable) bother to look it up? I
know you find it hard, so I've done it for you:

http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_8/CH08-1.html#HEADING1-206
 
P

Paul

Leigh Johnston said:
And here is the asm output:

; Listing generated by Microsoft (R) Optimizing Compiler Version
14.00.50727.762

TITLE C:\cpp\public.cpp
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC ?foo@@YAXPAH@Z ; foo
; Function compile flags: /Odtp
_TEXT SEGMENT
_p$ = 8 ; size = 4
?foo@@YAXPAH@Z PROC ; foo
; File c:\cpp\public.cpp
; Line 3
push ebp
mov ebp, esp
; Line 4
mov eax, DWORD PTR _p$[ebp]
mov DWORD PTR [eax], 7
; Line 5
pop ebp
ret 0
?foo@@YAXPAH@Z ENDP ; foo
_TEXT ENDS
PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
/*************************************/
_arr$ = -20 ; size = 20

/************************************/
The above line is the array type object.
This is a pointer in asm because array type objects do not exist in
asm.
/************************************/
_main PROC
; Line 7
push ebp
mov ebp, esp
sub esp, 20 ; 00000014H
; Line 8
mov DWORD PTR _arr$[ebp], 0
xor eax, eax
mov DWORD PTR _arr$[ebp+4], eax
mov DWORD PTR _arr$[ebp+8], eax
mov DWORD PTR _arr$[ebp+12], eax
mov DWORD PTR _arr$[ebp+16], eax
; Line 9
/**************************************/
lea ecx, DWORD PTR _arr$[ebp]
push ecx
/*************************************/
The above two lines push the address of the arrays first element onto
the stack prior to invokation of foo.
/*************************************/
call ?foo@@YAXPAH@Z ; foo
add esp, 4
; Line 11
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END


In the above asm listing arr is _arr$ , that is a pointer object that
has the value of -20.

It is not a pointer object; it is a constant.
No Leigh it's a pointer.

No it is a constant; an offset used in conjunction with the stack frame
pointer. You obviously do not understand assembly in addition to not
understanding C++.
Im assembly langauge a pointer is a variable whose value is the address, or
offset, of some other memory location.
 
P

Paul

Ian Collins said:
No, it is a constant value. How much x86 assembly programming have you
actually done? Not a lot I'd guess.


Did you (I sometimes doubt if you are capable) bother to look it up? I
know you find it hard, so I've done it for you:

http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_8/CH08-1.html#HEADING1-206

--

From the link you have posted you should refer to chapter 5.5 Pointer Data
types.
http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_5/CH05-1.html#HEADING1-197

"A pointer is simply a memory location whose value is the address (or index
if you prefer) of some other memory location. Pointers are very easy to
declare and use in an assembly language program. You don't even have to
worry about array indices or anything like that. In fact the only
complication you're going to run into is that the 80x86 supports two kinds
of pointers: near pointers and far pointers.

A near pointer is a 16 bit value that provides an offset into a segment. It
could be any segment but you will generally use the data segment (dseg in
SHELL.ASM). If you have a word variable p that contains 1000h then p
"points" at memory location 1000h in dseg. To access the word that p points
at you could use code like the following: "

The pointer _arr$ happens to be an offset into the text segment, but this
does not change the fact that it is a pointer.
It's value is -20 , that is a memory index or an offset.

A manifest constant is not a pointer. I found this thread discussing
manifest constants where nobody had even heard of it before, including our
friend Alf
http://www.velocityreviews.com/foru...lues-and-symbolic-and-manifest-constants.html
 
T

Thomas David Rivers

Paul said:
Oh right I though I was aggreing with you on your terms but it seems
that whether I discuss an array in one context you will discuss it in
another context.

I think an array is a contiguous sequence of elements but I can also
accept that an array identifier is called an array and that identifier
is a non modifiable object.
If I talk about an array in the context of an indentifier or in the
context of a sequence of objects you will change the correct and say I
am wrong.


An array is a contiguous sequence of objects and nothing more.
So no point in going any further .


OK! We've got a point of agreement..

Would you say that we both agree that an array is a contiguous set of
elements of the same type ; and that these elements can be accessed
via the indexing operator-[] ?

And, that there is nothing more to it?

(I want to drop this 'non-modifiable object' idea for the time being,
we can come back to that... and, we can later discover just why
it's "non-modifiable"... but, one thing at a time...)

If you can agree with that, then we can proceed to learn about how
this all works... it's really kinda neat. We can really build from this
basic understanding. And, I think you might find that it will all become
much more clear.

So - do we agree that an array is a contigous set of like-typed elements,
where the elements are accessed via the []-operator?

- Dave Rivers -
 
P

Paul

Thomas David Rivers said:
Paul said:
Oh right I though I was aggreing with you on your terms but it seems that
whether I discuss an array in one context you will discuss it in another
context.

I think an array is a contiguous sequence of elements but I can also
accept that an array identifier is called an array and that identifier is
a non modifiable object.
If I talk about an array in the context of an indentifier or in the
context of a sequence of objects you will change the correct and say I am
wrong.


An array is a contiguous sequence of objects and nothing more.
So no point in going any further .


OK! We've got a point of agreement..

Would you say that we both agree that an array is a contiguous set of
elements of the same type ; and that these elements can be accessed
via the indexing operator-[] ?

And, that there is nothing more to it?

(I want to drop this 'non-modifiable object' idea for the time being,
we can come back to that... and, we can later discover just why
it's "non-modifiable"... but, one thing at a time...)

If you can agree with that, then we can proceed to learn about how
this all works... it's really kinda neat. We can really build from this
basic understanding. And, I think you might find that it will all become
much more clear.

So - do we agree that an array is a contigous set of like-typed elements,
where the elements are accessed via the []-operator?
Yes I aggree with that.
 
P

Paul

Leigh Johnston said:
That is all fine and correct.


Yet again you are confusing different meanings of the term "segment".
'arr$' is certainly not a pointer and it is certainly not an offset into
the text segment.


'_arr$' is not a pointer in either sense (assembly or C++); '_arr$' is a
constant, an offset used in conjunction with the stack frame pointer.

<snip>

YOU NEED TO READ TWO BOOKS: One on assembly language programming and one
on C++ programming (or compiler design).
arr is a pointer , the same as px in the following code:

int main(){
int x=5;
int arr[3];
int* px= &x;
px=arr;
}


; Listing generated by Microsoft (R) Optimizing Compiler Version
14.00.50727.762

TITLE C:\cpp\public.cpp
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
_px$ = -20 ; size = 4
_arr$ = -16 ; size = 12
_x$ = -4 ; size = 4
_main PROC
; File c:\cpp\public.cpp
; Line 5
push ebp
mov ebp, esp
sub esp, 20 ; 00000014H
; Line 6
mov DWORD PTR _x$[ebp], 5
; Line 8
lea eax, DWORD PTR _x$[ebp]
mov DWORD PTR _px$[ebp], eax
; Line 9
lea ecx, DWORD PTR _arr$[ebp]
mov DWORD PTR _px$[ebp], ecx
; Line 10
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END
 
P

Paul

Leigh Johnston said:
No it isn't. Just because similar assembly is produced for dereferencing
a pointer on the stack and accessing an array element on the stack that
doesn't mean that a stack frame pointer offset (constant) is a pointer.
The assembly code pointer is what we are talking about here.
Stop being an idiot.
 

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
474,143
Messages
2,570,822
Members
47,368
Latest member
michaelsmithh

Latest Threads

Top