Problem with array objects

T

Thomas David Rivers

Paul said:
Paul said:
Paul wrote:



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.


So - next let's examine a rather simple declaration of an array in
C/C++.

int arr[5];



No do a dynamic array like so:
int* arr = new int[5];

Then there is no confusion about array objects, an array is simply
the region of memory storing the integer objects and nothing more.

Having read ahead you seem to be slowly introducing this "arr"
object into the equation without first aggreeing on a definition of
what exactly "arr" is. And that is what was the original argument.

In the above example of a dynamic array there is no confusion that
"arr" is a pointer.

You are correct - what you have declared there is a pointer to an
integer,
(the `int *arr' portion), and that pointer is initialized with some
dynamically
allocated space (the `new' portion.) The dynamically allocated
space is a
contiguous set of 5 'int' elements (the `int[5]' portion.) The
pointer's name is 'arr'.

That's all well and good, but it is very different from what I was
talking about.

What I'd like to focus on is this simple declaration:

int arr[5];

Can we agree that the declaration of

int arr[5];

represents, at runtime, a set of 5 contiguous 'int' elements. The
name of the set of 5 contiguous elements it 'arr'. The name 'arr'
refers to the runtime location of the set of 5 contiguous elements.

If we can, I'd like to restrict the conversation to just that for the
moment... we can get to the other stuff soon enough... but, one
thing at a time.
Yes I agree with this, but before we can proceed any further we need
to agree on what exactly "arr" is.
You are calling it a name that refers to the contiguous sequence of
elements here.
I would like to establish just what exactly it is because it seems to
store a memory address as can be show with:
int arr[5];
int* p = arr;

So lets try to agree about what exactly arr is.
As you know I have been calling it an array type object.

That would basically be the next step...

However, I want to hold to the definition; 'arr' is simply the name
of the 5 contiquous int elements.

Now - let's take up the problem of assignment to a pointer...

Let's consider this snippet:

int i;
int *ip;

ip = &i;

would you agree that the semantics of that would be that
'i' is the name of an `int'. `ip' is the name of a pointer to an `int'.
The expression:

&i

denotes "the address of the `int' named `i'"

And the expression:

ip = &i;

denotes "compute the address of the `int' named 'i', store that
value into the pointer-to-`int' named `ip'."

Does that sound correct?

If so, then we can begin to look at your example involving `arr';
and - we can compare the two with considerations toward just
what it means to assign a value to the `int' pointer named `ip'.

But - one thing at a time.

- Dave Rivers -
 
P

Paul

A. Bolmarcich said:
[snip]
Ok sorry I lost track of these threads a little bit there.
SO what exactly is your arguemnt about arrays again?

I don't have an argument about arrays. I accept what is actually
in the C++ standard. For arrays this includes the sentence (from
paragraph 1 of 8.3.4 Arrays): "An object of array type contains a
contiguously allocated nonempty set of N sub-objects of type T."

I also accept that when the C++ standard does not specify a
difference in an operator when applied to an array and when applied
to a non-array, that there is no difference.

For example, what I snipped above included paragraphs from the C++
stanadard for the unary * and unary & operators. The C++ standard
does not specify a difference in those operators on an array and on
a non-array. Taking an address and dereferencing the resulting
pointer is the same with arrays and non-arrays.

I do not accept statements about C++ that are not supported by what
is in the C++ standard, such as a pointer to an array ((*)[])
referencing an "array-type" object that is distinct from the object
of array type that contains the elements of the array.

I have been responding to questions you have asked and questionable
statments that you have made. It is your choice whether to read
and respond to what I wrote that you silently snipped at this point.

So what, in your mind, is the object referred to by the C++ standard as a
non modifiable object of array type?
 
P

Paul

Leigh Johnston said:
Man you really don't have a clue, do you? I'll ask again, How
much
x86
assembly programming have you actually done?

It doesn't matter how much I claim to have done or how much you
claim to
have done. The fact of the matter is, apparently I know what a
pointer
is
and you don't.

I'll take that as "none".

A variable whose value is an address(or an offset) to another
memory
location is a pointer in assembly language.

The *number* -20 isn't a variable any more than arr in "#define
arr 20"
is.
Correct -20 is not a variable , it is the value of the variable.

It is the value of a constant. By your definition, if I write

#define arr -20

arr is a variable.

_arr$ = -20 ; size = 20

is the MASM equivalent of

#define arr = -20 // is arr a pointer?

It is declared in the text segment, it is not an offset into the
text
segment.

_arr$ is a variable that stores the value -20.

No, for the last time it is a constant. Please study a topic
before
posting about it. From the link I posted earlier:

"A manifest constant is a symbol name that represents some fixed
quantity during the assembly process. That is it is a symbolic
name
that represents some value. Equates are the mechanism MASM uses to
declare symbolic constants."

This is now way off topic. I suggest you find an assembly
programming
group and see how far you get there.

Its you that brought it up. And now you seem to be ruinning away
from
the argument because you are maybe starting to realise that _arr$
is a
pointer.


Look at the following code:

int main(){
int arr[3]={0};
int* px= arr;
px[1] = 7;
}

; 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$ = -16 ; size = 4
_arr$ = -12 ; size = 12
_main PROC
; File c:\cpp\public.cpp
; Line 5
push ebp
mov ebp, esp
sub esp, 16 ; 00000010H
; Line 6
mov DWORD PTR _arr$[ebp], 0
xor eax, eax
mov DWORD PTR _arr$[ebp+4], eax
mov DWORD PTR _arr$[ebp+8], eax
; Line 7
lea ecx, DWORD PTR _arr$[ebp]
mov DWORD PTR _px$[ebp], ecx
; Line 8
mov edx, DWORD PTR _px$[ebp]
mov DWORD PTR [edx+4], 7
; Line 9
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

Line 5-6 Creates a stack frame similar to below. It preserves ebp
on the
stack, then assgins the esp value to ebp and then decrements esp
by 16
bytes.
Line 6-7 Initialises the 3 integer objects , of the array, to 0.
Line 7-8 Stores the address of the first element at the location
_px$
points to.
Line 8-9 Moves the literal value of 7 into the 2nd element of the
array.


00001C [-------------]
000018 [--orig ebp---]<- orig esp
000014 [------0------] <-ebp
000010 [------7------]
00000C [------0------]
000008 [---00000C---] <- esp
000004 [-------------]
000000 [-------------]

After that ebp is popped and esp is back to its original value.
Face the facts about what a pointer is in assembly programming.
If you still do not accept these facts then I urge you to refer
to the
link I posted about pointer data types by Randy Hyde.

Now you are arguing with yourself: you have just shown that there is
no special hidden object which containing the address of the array
object; the only thing that contains the address of the array object
above is the pointer 'px'.

No there is a pointer named _arr$, which happens to be in the text
segment, it is not on the stack.

No, '_arr$' is not a pointer; '_arr$' is a constant used when emitting
machine code in the text segment. If does not exist as a separate
entity in the text segment. lrn2asm.

Just the same as the pointer _px$ is not on the stack.
Look at the value of _px$, it is -16, this doesn't mean it's not a
pointer. Its just a pointer that stores an offset, or an index into
the
stack.

The value of the pointer 'px' is stored on the stack at a location
stack frame pointer + '_px$' (a constant whose value is -16); we have
already told you this.


For:

lea ecx, DWORD PTR _arr$[ebp]

what will actually be emitted is:

lea ecx, DWORD PTR [ebp-12]

as '_arr$' is a constant; not a variable or a "pointer".

_arr$ holds an offset which is added to ebp to create the real
address.

Correct we have already told you this.

_arr$ is a constant only because it is stored in the read only text
segment. This does not mean it is not a pointer , it stores an offset
that points to the begining of the array.

As I have already said '_arr$' does not exist as a distinct separate
entity in the text segment; it used when emitting machine code in the
text segment.

A pointer does not need to store a real address a pointer can also
store
an offset, as in this case.

It is not a pointer; it is a constant used when emitting machine code.

Oh you want to go to machine code level now?
There is no pointers in machine code at all, your argument is nonsense.




Given my stack frame illustration _arr$ points to here:

00001C [-------------]
000018 [--orig ebp---] <- ebp
000014 [------0------]
000010 [------7------]
00000C [------0------] <- _arr$
000008 [---00000C---] <- esp
000004 [-------------]
000000 [-------------]

-12 is an offset into the stack frame, which is the location where
the
array begins.

Finally. Yes -12 is an offset into the stack frame; we have been
trying to tell you this for the past couple of days; -12 is not a
pointer or a variable it is a constant offset. A realistic and correct
stack frame illustration is:

123000 [-------------]
122FFC [--orig ebp---] <- ebp
123FF8 [------0------]
123FF4 [------7------]
123FF0 [------0------] <- ebp + _arr$
123FEC [---123FEC---] <- esp
123FE8 [-------------]
123FE4 [-------------]

Notice how I have replaced your deliberately misleading value of 12
(00000C) with a more realistic value that shows that the contents of
the pointer 'px' is unrelated to the number 12; its value is ebp +
_arr$ as encoded into the emitted machine code in the text segment.

There was no deliberate attempt to mislead, It was pure coincidence
that
the address turned out to be 12. You interpretation is wrong , the
value
of memory location 123FEC should be 123FF0.


Typical troll: deliberately ignoring my correction. On the small
chance that you didn't use your newsreader properly yes I did put the
wrong value in the illustration but that doesn't change the fact that
what I said (and my "interpretation") is correct: '_arr$' is not a
pointer it is a constant used when emitting machine code in the text
segment.
So a simple task like changing the ficticional addresses is obviously
too complicated for you.

Your original stack frame illustration also contained an error which you
silently corrected so following your logic you are also unable to perform
such a simple task.
My original illustration demonstrated knowledge of the code presented and
understanding of how the computer system works.
I didn't *silently* correct it, I corrected on small error that was a
text -> graphical asciiart mistake.
There is more complexity in what I did to interpret the code and convert
this into a stack ullustration than simply changing the ficticional
addresses.
You are the one without a clue: an object file contains machine code along
with relocation information and stack frame pointer offsets do not require
relocation.
True an object file does contain machine code but this does not change the
fact that you are changing the goalpoasts to a lower level of code, you will
eventually get to the point where you are saying that a binary file does not
contain pointers therefore _arr$ is not a pointer.

If I change the C++ code to

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

When you inspect the object file you will see that this array is not
optimised into a literal value at machine code level.

When I examine dumpbin arr is a symbol and its name is ?arr@@3PAHA (int *
arr)

Note that dumpbin displays this symbol with the addition info (int* arr),
this is compiled as a coff on a MS machine.
 
P

Paul

Thomas David Rivers said:
Paul said:
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.


So - next let's examine a rather simple declaration of an array in
C/C++.

int arr[5];



No do a dynamic array like so:
int* arr = new int[5];

Then there is no confusion about array objects, an array is simply the
region of memory storing the integer objects and nothing more.

Having read ahead you seem to be slowly introducing this "arr" object
into the equation without first aggreeing on a definition of what
exactly "arr" is. And that is what was the original argument.

In the above example of a dynamic array there is no confusion that
"arr" is a pointer.



You are correct - what you have declared there is a pointer to an
integer,
(the `int *arr' portion), and that pointer is initialized with some
dynamically
allocated space (the `new' portion.) The dynamically allocated space
is a
contiguous set of 5 'int' elements (the `int[5]' portion.) The pointer's
name is 'arr'.

That's all well and good, but it is very different from what I was
talking about.

What I'd like to focus on is this simple declaration:

int arr[5];

Can we agree that the declaration of

int arr[5];

represents, at runtime, a set of 5 contiguous 'int' elements. The
name of the set of 5 contiguous elements it 'arr'. The name 'arr'
refers to the runtime location of the set of 5 contiguous elements.

If we can, I'd like to restrict the conversation to just that for the
moment... we can get to the other stuff soon enough... but, one
thing at a time.
Yes I agree with this, but before we can proceed any further we need to
agree on what exactly "arr" is.
You are calling it a name that refers to the contiguous sequence of
elements here.
I would like to establish just what exactly it is because it seems to
store a memory address as can be show with:
int arr[5];
int* p = arr;

So lets try to agree about what exactly arr is.
As you know I have been calling it an array type object.

That would basically be the next step...

However, I want to hold to the definition; 'arr' is simply the name
of the 5 contiquous int elements.

Now - let's take up the problem of assignment to a pointer...

Let's consider this snippet:

int i;
int *ip;

ip = &i;

would you agree that the semantics of that would be that
'i' is the name of an `int'. `ip' is the name of a pointer to an `int'.
The expression:

&i

denotes "the address of the `int' named `i'"

And the expression:

ip = &i;

denotes "compute the address of the `int' named 'i', store that
value into the pointer-to-`int' named `ip'."

Does that sound correct?

If so, then we can begin to look at your example involving `arr';
and - we can compare the two with considerations toward just
what it means to assign a value to the `int' pointer named `ip'.
Yes this is agreeable. You may continue to the next step :)
 
P

Paul

Leigh Johnston said:
Leigh Johnston said:
On 27/05/2011 15:53, Paul wrote:

Man you really don't have a clue, do you? I'll ask again,
How
much
x86
assembly programming have you actually done?

It doesn't matter how much I claim to have done or how much
you
claim to
have done. The fact of the matter is, apparently I know what
a
pointer
is
and you don't.

I'll take that as "none".

A variable whose value is an address(or an offset) to another
memory
location is a pointer in assembly language.

The *number* -20 isn't a variable any more than arr in
"#define
arr 20"
is.
Correct -20 is not a variable , it is the value of the
variable.

It is the value of a constant. By your definition, if I write

#define arr -20

arr is a variable.

_arr$ = -20 ; size = 20

is the MASM equivalent of

#define arr = -20 // is arr a pointer?

It is declared in the text segment, it is not an offset into
the
text
segment.

_arr$ is a variable that stores the value -20.

No, for the last time it is a constant. Please study a topic
before
posting about it. From the link I posted earlier:

"A manifest constant is a symbol name that represents some fixed
quantity during the assembly process. That is it is a symbolic
name
that represents some value. Equates are the mechanism MASM
uses to
declare symbolic constants."

This is now way off topic. I suggest you find an assembly
programming
group and see how far you get there.

Its you that brought it up. And now you seem to be ruinning away
from
the argument because you are maybe starting to realise that _arr$
is a
pointer.


Look at the following code:

int main(){
int arr[3]={0};
int* px= arr;
px[1] = 7;
}

; 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$ = -16 ; size = 4
_arr$ = -12 ; size = 12
_main PROC
; File c:\cpp\public.cpp
; Line 5
push ebp
mov ebp, esp
sub esp, 16 ; 00000010H
; Line 6
mov DWORD PTR _arr$[ebp], 0
xor eax, eax
mov DWORD PTR _arr$[ebp+4], eax
mov DWORD PTR _arr$[ebp+8], eax
; Line 7
lea ecx, DWORD PTR _arr$[ebp]
mov DWORD PTR _px$[ebp], ecx
; Line 8
mov edx, DWORD PTR _px$[ebp]
mov DWORD PTR [edx+4], 7
; Line 9
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

Line 5-6 Creates a stack frame similar to below. It preserves ebp
on the
stack, then assgins the esp value to ebp and then decrements esp
by 16
bytes.
Line 6-7 Initialises the 3 integer objects , of the array, to 0.
Line 7-8 Stores the address of the first element at the location
_px$
points to.
Line 8-9 Moves the literal value of 7 into the 2nd element of the
array.


00001C [-------------]
000018 [--orig ebp---]<- orig esp
000014 [------0------] <-ebp
000010 [------7------]
00000C [------0------]
000008 [---00000C---] <- esp
000004 [-------------]
000000 [-------------]

After that ebp is popped and esp is back to its original value.
Face the facts about what a pointer is in assembly programming.
If you still do not accept these facts then I urge you to refer
to the
link I posted about pointer data types by Randy Hyde.

Now you are arguing with yourself: you have just shown that
there is
no special hidden object which containing the address of the array
object; the only thing that contains the address of the array
object
above is the pointer 'px'.

No there is a pointer named _arr$, which happens to be in the text
segment, it is not on the stack.

No, '_arr$' is not a pointer; '_arr$' is a constant used when
emitting
machine code in the text segment. If does not exist as a separate
entity in the text segment. lrn2asm.

Just the same as the pointer _px$ is not on the stack.
Look at the value of _px$, it is -16, this doesn't mean it's not a
pointer. Its just a pointer that stores an offset, or an index into
the
stack.

The value of the pointer 'px' is stored on the stack at a location
stack frame pointer + '_px$' (a constant whose value is -16); we
have
already told you this.


For:

lea ecx, DWORD PTR _arr$[ebp]

what will actually be emitted is:

lea ecx, DWORD PTR [ebp-12]

as '_arr$' is a constant; not a variable or a "pointer".

_arr$ holds an offset which is added to ebp to create the real
address.

Correct we have already told you this.

_arr$ is a constant only because it is stored in the read only text
segment. This does not mean it is not a pointer , it stores an
offset
that points to the begining of the array.

As I have already said '_arr$' does not exist as a distinct separate
entity in the text segment; it used when emitting machine code in
the
text segment.

A pointer does not need to store a real address a pointer can also
store
an offset, as in this case.

It is not a pointer; it is a constant used when emitting machine
code.

Oh you want to go to machine code level now?
There is no pointers in machine code at all, your argument is
nonsense.




Given my stack frame illustration _arr$ points to here:

00001C [-------------]
000018 [--orig ebp---] <- ebp
000014 [------0------]
000010 [------7------]
00000C [------0------] <- _arr$
000008 [---00000C---] <- esp
000004 [-------------]
000000 [-------------]

-12 is an offset into the stack frame, which is the location
where the
array begins.

Finally. Yes -12 is an offset into the stack frame; we have been
trying to tell you this for the past couple of days; -12 is not a
pointer or a variable it is a constant offset. A realistic and
correct
stack frame illustration is:

123000 [-------------]
122FFC [--orig ebp---] <- ebp
123FF8 [------0------]
123FF4 [------7------]
123FF0 [------0------] <- ebp + _arr$
123FEC [---123FEC---] <- esp
123FE8 [-------------]
123FE4 [-------------]

Notice how I have replaced your deliberately misleading value of 12
(00000C) with a more realistic value that shows that the contents of
the pointer 'px' is unrelated to the number 12; its value is ebp +
_arr$ as encoded into the emitted machine code in the text segment.

There was no deliberate attempt to mislead, It was pure coincidence
that
the address turned out to be 12. You interpretation is wrong , the
value
of memory location 123FEC should be 123FF0.


Typical troll: deliberately ignoring my correction. On the small
chance that you didn't use your newsreader properly yes I did put the
wrong value in the illustration but that doesn't change the fact that
what I said (and my "interpretation") is correct: '_arr$' is not a
pointer it is a constant used when emitting machine code in the text
segment.

So a simple task like changing the ficticional addresses is obviously
too complicated for you.

Your original stack frame illustration also contained an error which
you silently corrected so following your logic you are also unable to
perform such a simple task.
My original illustration demonstrated knowledge of the code presented
and understanding of how the computer system works.
I didn't *silently* correct it, I corrected on small error that was a
text -> graphical asciiart mistake.
There is more complexity in what I did to interpret the code and convert
this into a stack ullustration than simply changing the ficticional
addresses.

No it contained a major error (ebp pointing to the wrong thing) but meh
who cares? You are the one who pounced on *my* minor error; an error
which I publicly corrected; a correction you chose to ignore to try and
score points due to your immaturity; immaturity which you have displayed
numerous times in this newsgroup.
omg.
You changed the contents of the stack to something that was incorrect.
And I didn't pounce on it, I simply pointed out your error. You had not
posted a correction at the time I was replying so I didnt even see your
correction when I was posting.
Any immaturity is coming from your corner, accept your error and move on.
'_arr$' is not a pointer; it is a constant used when emitting machine code
for the text segment; it is a transient artefact of the compilation
process.

The constantness does not define whether or not its a pointer.
It's complete nonsense to say "its not a pointer its a constant"
Its a constant pointer therefore its both a constant and a pointer.
If I change the C++ code to

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

When you inspect the object file you will see that this array is not
optimised into a literal value at machine code level.

What has this got to do with what we have been talking about? Here the
array is of static storage duration so has a fixed address requiring
relocation during linking.
When I examine dumpbin arr is a symbol and its name is ?arr@@3PAHA (int
* arr)

Of course arr has a symbolic name; what is your point? This has nothing
to do with the possible existance of this mythical object of yours that
contains the memory address of an array.

The point is that this "arr" object exists as a pointer to the array.
Your basic problem (in addition to immaturity) is one of pride and of
being unable to own up to your mistakes. You won't even apologize for
your previous obnoxious insults.
You are the one dishing out the insults with every post you make , not me.
 
T

Thomas David Rivers

Paul said:
Paul said:
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.


So - next let's examine a rather simple declaration of an array
in C/C++.

int arr[5];




No do a dynamic array like so:
int* arr = new int[5];

Then there is no confusion about array objects, an array is simply
the region of memory storing the integer objects and nothing more.

Having read ahead you seem to be slowly introducing this "arr"
object into the equation without first aggreeing on a definition
of what exactly "arr" is. And that is what was the original argument.

In the above example of a dynamic array there is no confusion that
"arr" is a pointer.



You are correct - what you have declared there is a pointer to an
integer,
(the `int *arr' portion), and that pointer is initialized with
some dynamically
allocated space (the `new' portion.) The dynamically allocated
space is a
contiguous set of 5 'int' elements (the `int[5]' portion.) The
pointer's name is 'arr'.

That's all well and good, but it is very different from what I was
talking about.

What I'd like to focus on is this simple declaration:

int arr[5];

Can we agree that the declaration of

int arr[5];

represents, at runtime, a set of 5 contiguous 'int' elements. The
name of the set of 5 contiguous elements it 'arr'. The name 'arr'
refers to the runtime location of the set of 5 contiguous elements.

If we can, I'd like to restrict the conversation to just that for the
moment... we can get to the other stuff soon enough... but, one
thing at a time.

Yes I agree with this, but before we can proceed any further we need
to agree on what exactly "arr" is.
You are calling it a name that refers to the contiguous sequence of
elements here.
I would like to establish just what exactly it is because it seems
to store a memory address as can be show with:
int arr[5];
int* p = arr;

So lets try to agree about what exactly arr is.
As you know I have been calling it an array type object.

That would basically be the next step...

However, I want to hold to the definition; 'arr' is simply the name
of the 5 contiquous int elements.

Now - let's take up the problem of assignment to a pointer...

Let's consider this snippet:

int i;
int *ip;

ip = &i;

would you agree that the semantics of that would be that
'i' is the name of an `int'. `ip' is the name of a pointer to an `int'.
The expression:

&i

denotes "the address of the `int' named `i'"

And the expression:

ip = &i;

denotes "compute the address of the `int' named 'i', store that
value into the pointer-to-`int' named `ip'."

Does that sound correct?

If so, then we can begin to look at your example involving `arr';
and - we can compare the two with considerations toward just
what it means to assign a value to the `int' pointer named `ip'.
Yes this is agreeable. You may continue to the next step :)

OK - let's review - so we know we're on the same page:

int arr[5];

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

int *ip;

`ip' is the name of a variable that can contain the address of an `int',
it is a "pointer to int".

And:

int i;

`i' is the name of an `int'-tpe variable.

The expression:

ip=&i;

computes the address of `i', and places that value into the variable
`ip'.

This is what we've agreed to thus far... right?

This establishes that `ip' is not the same type as `arr'.
`arr' is the contiguous set of 5 `int' elements, `ip' can contain
the address of an `int', it can "point to" an `int'.

There is nothing new in that statement; it is a re-statement
of the preceeding items we've agreed to (in that `arr' is the
set, `ip' is a single pointer.)

Now - in a programming language like C/C++, typically the
language might enforce rules regarding assignent. One such
rule is that assignments can only be made from a value of the
destination type, and that if the types are not the same, then
some mechanism is employed to convert from oen type to another
(if possible).

As an example:

double d;
int i;

d = i;

The variable `i' is an `int'; `d' is a `double'. You might decide,
in a programming language, that such an assignment not be
allowed - but it is in C/C++ because the `int' value contained
in `i' will be, at runtime, converted to a `double' and then
stored in the variable `d'.

In this instance, would you say there was a "magic"/secret object
of type `double' that was created along with `i' to contain the
converted result before assigning the value to `d'? Or, would
you say that the conversion simply occurs as a matter-of-course?

I think, most people would say that the compiler generates code
which effects the conversion at runtime, so that `i' is, at runtime,
converted to a double, and the temporary value that results from
that conversion is stored in `d'.

But; this is a well-defined conversion... does the C/C++ language
definition provide any such mechanism for this snippet:

int *ip;
int arr[5];

ip = arr;

Given the definitions (to which we've all agreed), `ip' is a pointer
to an `int', and `arr' is a contigous set of 5 `int' elements. How could
those two types be reconciled to allow this assignment???

What is going on here??

As it so happens, the designers of C (and, by extension, C++) considered
this problem, and provide a mechanism by which such an assignment
is accomplished.

This mechanism has been written down in the various standard documents,
so that everyone can read it and truly understand what is meant by
that assignment.

First - recall, as you have agreed, that arr' is an array of 5 `int'
elements.

(we clearly cannot assign 5 `int' elements in-toto to a pointer to a
single `int',
in a reasonable type-system, at least.)

So - given that `arr' is an array, I will quote from the C standard,
which might
be a little more clear than the C++ one (simply for this discussion, the C++
definition is similar):

Section 6.3.2.1 Lvalues, arrays, and function designators

Paragraph #1:

An lvalue is an expression with an object type or an incomplete
type other than void.

(that is, `arr' is an "lvalue", it is an "lvalue" with an object type
of int[5].
An "lvalue" in C is basically what can appear on the left-hand-side of the
assignment operator, the opposing "rvalue" appears on the right-hand-side.
That is, you assign the rvalue to the lvalue. In this case, `arr' is
an lvalue,
until you get to the next step.)

Paragraph #3:

Except when it is the operand of the sizeof operator or the unary &
operator, or is a string literal used to initialize an array, an
expression
that has type "array of type" is converted to an expression
"pointer to type"
that points to the initial element of the array object and it is
not an lvalue.

In this example, `arr' is not the operand of sizeof(), nor the unary &,
an it
is not a string literal to initialize an array. Thus, the conversion
applies.

So... what do we have in this:

int *ip;
int arr[5];

ip = arr;

Let's take the expression 'arr', which is the value being assigned.

According to the rules, it is an "lvalue".. it's type (as we agreed) is
an array of 5 int elements. When such an expression is used, the
language definition indicates that it should be converted to an
expression that is a pointer to the element type. The value
of that expression is a pointer to the first element. After that,
the expression is no longer an "lvalue" (it can't be assigned to,
hence it is not `modifiable'). [As an aside, the effect of not being
an "lvalue" is that it can't appear on the left-hand-side of the assignment
operator, thus you cannot have: arr = <something>; because 'arr'
would be converted to the non-lvalue expression.]

So, following that logic; the semantics of the expression `arr',
are completely the same as if this was this expression:

ip = (&arr[0]);

Do you not agree that the expression "&arr[0]" is the address of
the first element of `arr'?

Clearly the type of "&arr[0]" (the address of the first `int' element
of `arr') is the address of a single `int'.

Thus, the assignment is valid, and the program is valid.

Now. did the C/C++ language definition provide a separate object to compute
"&arr[0]"?

I believe, we agreed before that there was no separate object
in this snippet:

int *ip;
int i;

ip = &i;

I recall we both agreed that the semantics of that were that the
address of `i' was computed, and that value was placed in `ip'.

Similarly, this snippet:

int *ip;
int arr[5];

ip = (&arr[0]);

would simply compute the address of the first (0th) element of `arr'
and place that value in `ip'. There would be no separate object
required to be a pointer to the array... there is simply the array
and the fact that we can compute its address when needed.

And, because of the rule I cited above, this snippet:

int *ip;
int arr[5];

ip = arr;

is equivalent to the previous one (in that `arr' is an lvalue expression of
an array type, and it is therefor converted to a pointer to the array's
first element.)

So, you see, there is no separate "object" of any kind defined by the
language,
nor required in the implementation. It's simply a matter of following
the rules
set out in the C/C++ definition.

If you agree with all of this, then I'd like to discuss how the
[]-operator (indexing)
is defined... it simply "falls out" from this very simple approach.
And, it
is frequently why people confuse pointers-and-arrays.

To recap:

1) An array is a contigous set of same-typed elements.
2) A pointer to a variable that contains an address.
3) A pointer is not an array, an array is not a pointer.
4) The C/C++ languages provide for situations where implicit
conversions occur.
5) One such situation is that when an expression is an lvalue,
and the type of that expression is an array; the expression
is converted to an expression that is a pointer to the first
element of the array.


So - you see - it's really rather simple, no actual "magic" behind
this at all.. no magic 'array type object' or anything like that.
Just some basic definitions on which to build...

If you agre with all of this, then, as I mentioned above, I'd like to
explore how the indexing operator [] works; especially its relationship
to pointer arithmetic. And, we should explore the caveats mentioned
in the conversion rule (particularly, the & operator when applied to
an expression of array type.)

- Dave Rivers -
 
P

Paul

Leigh Johnston said:
Man you really don't have a clue, do you? I'll ask
again, How
much
x86
assembly programming have you actually done?

It doesn't matter how much I claim to have done or how much
you
claim to
have done. The fact of the matter is, apparently I know
what a
pointer
is
and you don't.

I'll take that as "none".

A variable whose value is an address(or an offset) to
another
memory
location is a pointer in assembly language.

The *number* -20 isn't a variable any more than arr in
"#define
arr 20"
is.
Correct -20 is not a variable , it is the value of the
variable.

It is the value of a constant. By your definition, if I write

#define arr -20

arr is a variable.

_arr$ = -20 ; size = 20

is the MASM equivalent of

#define arr = -20 // is arr a pointer?

It is declared in the text segment, it is not an offset into
the
text
segment.

_arr$ is a variable that stores the value -20.

No, for the last time it is a constant. Please study a topic
before
posting about it. From the link I posted earlier:

"A manifest constant is a symbol name that represents some
fixed
quantity during the assembly process. That is it is a symbolic
name
that represents some value. Equates are the mechanism MASM
uses to
declare symbolic constants."

This is now way off topic. I suggest you find an assembly
programming
group and see how far you get there.

Its you that brought it up. And now you seem to be ruinning
away
from
the argument because you are maybe starting to realise that
_arr$
is a
pointer.


Look at the following code:

int main(){
int arr[3]={0};
int* px= arr;
px[1] = 7;
}

; 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$ = -16 ; size = 4
_arr$ = -12 ; size = 12
_main PROC
; File c:\cpp\public.cpp
; Line 5
push ebp
mov ebp, esp
sub esp, 16 ; 00000010H
; Line 6
mov DWORD PTR _arr$[ebp], 0
xor eax, eax
mov DWORD PTR _arr$[ebp+4], eax
mov DWORD PTR _arr$[ebp+8], eax
; Line 7
lea ecx, DWORD PTR _arr$[ebp]
mov DWORD PTR _px$[ebp], ecx
; Line 8
mov edx, DWORD PTR _px$[ebp]
mov DWORD PTR [edx+4], 7
; Line 9
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

Line 5-6 Creates a stack frame similar to below. It preserves
ebp
on the
stack, then assgins the esp value to ebp and then decrements
esp
by 16
bytes.
Line 6-7 Initialises the 3 integer objects , of the array, to
0.
Line 7-8 Stores the address of the first element at the
location
_px$
points to.
Line 8-9 Moves the literal value of 7 into the 2nd element of
the
array.


00001C [-------------]
000018 [--orig ebp---]<- orig esp
000014 [------0------] <-ebp
000010 [------7------]
00000C [------0------]
000008 [---00000C---] <- esp
000004 [-------------]
000000 [-------------]

After that ebp is popped and esp is back to its original value.
Face the facts about what a pointer is in assembly programming.
If you still do not accept these facts then I urge you to refer
to the
link I posted about pointer data types by Randy Hyde.

Now you are arguing with yourself: you have just shown that
there is
no special hidden object which containing the address of the
array
object; the only thing that contains the address of the array
object
above is the pointer 'px'.

No there is a pointer named _arr$, which happens to be in the
text
segment, it is not on the stack.

No, '_arr$' is not a pointer; '_arr$' is a constant used when
emitting
machine code in the text segment. If does not exist as a separate
entity in the text segment. lrn2asm.

Just the same as the pointer _px$ is not on the stack.
Look at the value of _px$, it is -16, this doesn't mean it's not
a
pointer. Its just a pointer that stores an offset, or an index
into
the
stack.

The value of the pointer 'px' is stored on the stack at a location
stack frame pointer + '_px$' (a constant whose value is -16); we
have
already told you this.


For:

lea ecx, DWORD PTR _arr$[ebp]

what will actually be emitted is:

lea ecx, DWORD PTR [ebp-12]

as '_arr$' is a constant; not a variable or a "pointer".

_arr$ holds an offset which is added to ebp to create the real
address.

Correct we have already told you this.

_arr$ is a constant only because it is stored in the read only
text
segment. This does not mean it is not a pointer , it stores an
offset
that points to the begining of the array.

As I have already said '_arr$' does not exist as a distinct
separate
entity in the text segment; it used when emitting machine code
in the
text segment.

A pointer does not need to store a real address a pointer can
also
store
an offset, as in this case.

It is not a pointer; it is a constant used when emitting machine
code.

Oh you want to go to machine code level now?
There is no pointers in machine code at all, your argument is
nonsense.




Given my stack frame illustration _arr$ points to here:

00001C [-------------]
000018 [--orig ebp---] <- ebp
000014 [------0------]
000010 [------7------]
00000C [------0------] <- _arr$
000008 [---00000C---] <- esp
000004 [-------------]
000000 [-------------]

-12 is an offset into the stack frame, which is the location
where the
array begins.

Finally. Yes -12 is an offset into the stack frame; we have been
trying to tell you this for the past couple of days; -12 is not a
pointer or a variable it is a constant offset. A realistic and
correct
stack frame illustration is:

123000 [-------------]
122FFC [--orig ebp---] <- ebp
123FF8 [------0------]
123FF4 [------7------]
123FF0 [------0------] <- ebp + _arr$
123FEC [---123FEC---] <- esp
123FE8 [-------------]
123FE4 [-------------]

Notice how I have replaced your deliberately misleading value of
12
(00000C) with a more realistic value that shows that the
contents of
the pointer 'px' is unrelated to the number 12; its value is ebp +
_arr$ as encoded into the emitted machine code in the text
segment.

There was no deliberate attempt to mislead, It was pure coincidence
that
the address turned out to be 12. You interpretation is wrong , the
value
of memory location 123FEC should be 123FF0.


Typical troll: deliberately ignoring my correction. On the small
chance that you didn't use your newsreader properly yes I did put
the
wrong value in the illustration but that doesn't change the fact
that
what I said (and my "interpretation") is correct: '_arr$' is not a
pointer it is a constant used when emitting machine code in the text
segment.

So a simple task like changing the ficticional addresses is obviously
too complicated for you.

Your original stack frame illustration also contained an error which
you silently corrected so following your logic you are also unable to
perform such a simple task.

My original illustration demonstrated knowledge of the code presented
and understanding of how the computer system works.
I didn't *silently* correct it, I corrected on small error that was a
text -> graphical asciiart mistake.
There is more complexity in what I did to interpret the code and
convert
this into a stack ullustration than simply changing the ficticional
addresses.

No it contained a major error (ebp pointing to the wrong thing) but
meh who cares? You are the one who pounced on *my* minor error; an
error which I publicly corrected; a correction you chose to ignore to
try and score points due to your immaturity; immaturity which you have
displayed numerous times in this newsgroup.
omg.
You changed the contents of the stack to something that was incorrect.
And I didn't pounce on it, I simply pointed out your error. You had not
posted a correction at the time I was replying so I didnt even see your
correction when I was posting.
Any immaturity is coming from your corner, accept your error and move on.

Accept my error? I publicly posted a correction; you silently fixed your
error with no acknowledgement. Move on? Certainly as it is trivial.
The constantness does not define whether or not its a pointer.
It's complete nonsense to say "its not a pointer its a constant"
Its a constant pointer therefore its both a constant and a pointer.

It is an integer constant representing an offset to be applied to a stack
frame pointer; it is NOT a pointer for any definition of "pointer"; it is
like saying 'foo' below is a C++ pointer because we add it to a C++
pointer:

const std::size_t foo = 42;
int *p = ...;
int *p2 = p + foo; // is foo a pointer? don't be stupid.
No incorrect , you said it was not a pointer in assembly language.
Ovbioustly its not a C++ pointer, its an array type object.
In C++ we say something is a T becaus eit has a type T, for example:
int x; //x is an integer because of its type.
int* p; //p is a pointer because of its type
etc etc

In assembly there are no types and a variable or constant is simply data,
its purpose defines what it is.
If its purpose is to to store another memory location, or an offset to such,
then it is a pointer.
If I change the C++ code to

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

When you inspect the object file you will see that this array is not
optimised into a literal value at machine code level.

What has this got to do with what we have been talking about? Here the
array is of static storage duration so has a fixed address requiring
relocation during linking.


When I examine dumpbin arr is a symbol and its name is ?arr@@3PAHA (int
* arr)

Of course arr has a symbolic name; what is your point? This has
nothing to do with the possible existance of this mythical object of
yours that contains the memory address of an array.

The point is that this "arr" object exists as a pointer to the array.

Wrong yet again. After linking there is nothing that can be construed as
being a pointer to the array for any definition of "pointer". After
linking and relocation any references to 'arr' will be directly replaced
with the address of the array, no pointers.

I'm talking about object code, not after linking.
So you are wrong because you are talking about the wrong thing altogether.
One only has to look at your previous posts to this newsgroup to see who
has been dishing out the insults.
I only insult back , my insults are justified.
You just start insulting anyone who disagrees with you.
 
P

Paul

Thomas David Rivers said:
Paul said:
Paul wrote:




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.


So - next let's examine a rather simple declaration of an array in
C/C++.

int arr[5];




No do a dynamic array like so:
int* arr = new int[5];

Then there is no confusion about array objects, an array is simply
the region of memory storing the integer objects and nothing more.

Having read ahead you seem to be slowly introducing this "arr" object
into the equation without first aggreeing on a definition of what
exactly "arr" is. And that is what was the original argument.

In the above example of a dynamic array there is no confusion that
"arr" is a pointer.



You are correct - what you have declared there is a pointer to an
integer,
(the `int *arr' portion), and that pointer is initialized with some
dynamically
allocated space (the `new' portion.) The dynamically allocated space
is a
contiguous set of 5 'int' elements (the `int[5]' portion.) The
pointer's name is 'arr'.

That's all well and good, but it is very different from what I was
talking about.

What I'd like to focus on is this simple declaration:

int arr[5];

Can we agree that the declaration of

int arr[5];

represents, at runtime, a set of 5 contiguous 'int' elements. The
name of the set of 5 contiguous elements it 'arr'. The name 'arr'
refers to the runtime location of the set of 5 contiguous elements.

If we can, I'd like to restrict the conversation to just that for the
moment... we can get to the other stuff soon enough... but, one
thing at a time.

Yes I agree with this, but before we can proceed any further we need to
agree on what exactly "arr" is.
You are calling it a name that refers to the contiguous sequence of
elements here.
I would like to establish just what exactly it is because it seems to
store a memory address as can be show with:
int arr[5];
int* p = arr;

So lets try to agree about what exactly arr is.
As you know I have been calling it an array type object.



That would basically be the next step...

However, I want to hold to the definition; 'arr' is simply the name
of the 5 contiquous int elements.

Now - let's take up the problem of assignment to a pointer...

Let's consider this snippet:

int i;
int *ip;

ip = &i;

would you agree that the semantics of that would be that
'i' is the name of an `int'. `ip' is the name of a pointer to an `int'.
The expression:

&i

denotes "the address of the `int' named `i'"

And the expression:

ip = &i;

denotes "compute the address of the `int' named 'i', store that
value into the pointer-to-`int' named `ip'."

Does that sound correct?

If so, then we can begin to look at your example involving `arr';
and - we can compare the two with considerations toward just
what it means to assign a value to the `int' pointer named `ip'.
Yes this is agreeable. You may continue to the next step :)

OK - let's review - so we know we're on the same page:

int arr[5];

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

int *ip;

`ip' is the name of a variable that can contain the address of an `int',
it is a "pointer to int".

And:

int i;

`i' is the name of an `int'-tpe variable.

The expression:
ip=&i;

computes the address of `i', and places that value into the variable
`ip'.

This is what we've agreed to thus far... right? Yes ok.

This establishes that `ip' is not the same type as `arr'.
`arr' is the contiguous set of 5 `int' elements, `ip' can contain
the address of an `int', it can "point to" an `int'.
No , I agree that ip 'is' not the same type as 'arr' but the next part where
you say:

"`arr' is the contiguous set of 5 `int' elements"
I disagree with this because..
We agreed that 'arr' was a name for the 5 contiguous int objects, which is
not the same as saying it is the 5 objects.

The rest of what you say re: "ip can contain the address of an int, it can
point to an int" , I agree with more or less. I say 'more or less' because I
think the term 'contain' could be replaced with something more fitting like
perhaps 'store' or 'hold', but its just nitpicking terminology I guess.

However the point I made about 'arr' not being the 5 integer objects but a
name for them is not nitpicking terminology IMO, and I think we need to
resolve this difference of opinions before we can proceed.

There is nothing new in that statement; it is a re-statement
of the preceeding items we've agreed to (in that `arr' is the
set, `ip' is a single pointer.)
I think there is something new because you have changed the meaning of 'arr'
from (1) to (2)
1) a "name" for the 5 integer objects
2) the 5 integer objects.
Now - in a programming language like C/C++, typically the
language might enforce rules regarding assignent. One such
rule is that assignments can only be made from a value of the
destination type, and that if the types are not the same, then
some mechanism is employed to convert from oen type to another
(if possible).

As an example:

double d;
int i;

d = i;

The variable `i' is an `int'; `d' is a `double'. You might decide,
in a programming language, that such an assignment not be
allowed - but it is in C/C++ because the `int' value contained
in `i' will be, at runtime, converted to a `double' and then
stored in the variable `d'.
Are you sure this is converted at runtime?
I would've though this would be converted at compile time.

I'm not sure, OTTOMH, but I can see how this is possible because there
would be no loss of information, not so for the reverese though i.e: double
to integer.
In this instance, would you say there was a "magic"/secret object
of type `double' that was created along with `i' to contain the
converted result before assigning the value to `d'? Or, would
you say that the conversion simply occurs as a matter-of-course?

TBH I would need to refer to documentation about conversions from integer to
double.
From my previous studies of computer programming I know about fp type
consisting of a mantissa and exponential etc, but I think different systems
implement fp numbers in different ways and I would probably refer to the
correct documentation to confirm the exact implementation for conversion
from integer to fp for the target system.

I think, most people would say that the compiler generates code
which effects the conversion at runtime, so that `i' is, at runtime,
converted to a double, and the temporary value that results from
that conversion is stored in `d'.
I don't see why this woud be a runtime conversion, as oppose to compile time
conversion.

But; this is a well-defined conversion... does the C/C++ language
definition provide any such mechanism for this snippet:

I don't know anything about this conversion , this is kinda straying of the
subject a bit but if you care to discuss this further I would be willing to
investigate it in order to fully understand it.
int *ip;
int arr[5];

ip = arr;

Given the definitions (to which we've all agreed), `ip' is a pointer
to an `int', and `arr' is a contigous set of 5 `int' elements. How
could
those two types be reconciled to allow this assignment???
But I disagree with this step you have taken to promote 'arr' from a name
that refers to a contiguous set of 5 integers to actually being the
contiguous set of 5 integers.
What is going on here??
I don't know :)
I think we need to stop here and resolve this disagreement about what 'arr'
is.
Is it a name that refers to the array of integers, or is it actually the
array of integers.
As it so happens, the designers of C (and, by extension, C++) considered
this problem, and provide a mechanism by which such an assignment
is accomplished.

This mechanism has been written down in the various standard documents,
so that everyone can read it and truly understand what is meant by
that assignment.

First - recall, as you have agreed, that arr' is an array of 5 `int'
elements.
No I didn't.
I agreed that 'arr' was simply the name for 5 contiguous integer objects, I
did not agree that 'arr' WAS the contiguous set of integer objects.
(we clearly cannot assign 5 `int' elements in-toto to a pointer to a
single `int',
in a reasonable type-system, at least.)

So - given that `arr' is an array, I will quote from the C standard, which
might

Well you have certainly promoted 'arr' in this statement.
We agreed that 'arr' was a name for the contiguous set of integer objects.
Now you seem to defined 'arr' as actually being the contiguous set of
integer object, which I dsiagree with.

If we look at the data stored in the contiguous set of integer objects, it
is not the same data that is stored in 'arr'.
be a little more clear than the C++ one (simply for this discussion, the
C++
definition is similar):

Section 6.3.2.1 Lvalues, arrays, and function designators

Paragraph #1:

An lvalue is an expression with an object type or an incomplete
type other than void.

(that is, `arr' is an "lvalue", it is an "lvalue" with an object type of
int[5]. An "lvalue" in C is basically what can appear on the
left-hand-side of the
assignment operator, the opposing "rvalue" appears on the right-hand-side.
That is, you assign the rvalue to the lvalue. In this case, `arr' is an
lvalue,
until you get to the next step.)

The problem with this is you cannot assign to 'arr', except during
initialisation.
It's non modifiable AFAICT.

I think we need to go back to where we disagree and resolve that before
proceeding any further.
<snip>
 
P

Paul

Leigh Johnston said:
[snip]
It is an integer constant representing an offset to be applied to a
stack frame pointer; it is NOT a pointer for any definition of
"pointer"; it is like saying 'foo' below is a C++ pointer because we
add it to a C++ pointer:

const std::size_t foo = 42;
int *p = ...;
int *p2 = p + foo; // is foo a pointer? don't be stupid.
No incorrect , you said it was not a pointer in assembly language.
Ovbioustly its not a C++ pointer, its an array type object.

Do you not understand the meaning of the words "it is like"? Do you know
what an "analogy" is? Have you ever bothered to try "lateral thinking"?

I never said it was a C++ pointer; I was giving you a C++ analogy of why a
pointer offset (for any definition of "pointer") is not a pointer.
But a pointer in assembly is not the same as a pointer in C++. A pointer in
C++ is a pointer type object, or an object of pointer type.
Assembly does not have types, a pointer in assembly is the same as any other
variable or constant, except that its intended use is to store an address(or
an offset) to another memory location.
 
J

Joshua Maurice

OK - let's review - so we know we're on the same page:

   int arr[5];

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

   int *ip;

`ip' is the name of a variable that can contain the address of an `int',
it is a "pointer to int".

And:

  int i;

`i' is the name of an `int'-tpe variable.

The expression:

   ip=&i;

computes the address of `i', and places that value into the variable
`ip'.

This is what we've agreed to thus far... right?

If you care, I've deciphered what Paul's on about. I don't feel like
arguing with him, but it's painful watching you struggle as I did to
decipher what he's rambling about.

I'm not exactly sure of the specifics of what Paul thinks, but it's
more or less this. Paul thinks that there are two different kinds of
array objects. Consider:
int x[5];
Paul agrees that there is a segment of memory which contains 5
contiguous int objects. Depending on context (this is the part I
haven't fully worked out yet), Paul also thinks that there is some
other kind of object of array type. He thinks that this second kind of
array object, quote unquote "array type object", contains merely a
pointer to the first int object of the 5 int contiguous int objects.
He thinks that this pointer occupies a distinct and separate piece of
memory from the 5 contiguous int objects. He thinks that the terms
"array object" and "object of array type" do not refer to the region
of memory of the 5 contiguous int objects.

His reason for believing so is one part of the C++ standard which
mentions that array objects are not modifiable. As I've tried to
explain to him, the individual array element sub-objects are
modifiable, but the array object is not modifiable. What that means is
that the individual elements, if of built-in type, may appear on the
left hand side of a built in assignment operator, but expressions of
array type may not appear on the left hand side of the build in
assignment operator. It's a statement about lvalues and rvalues and
the C++ type system, not of any sort of restrictions on writes to the
array elements or whatever. Paul thinks that this is a contradiction
in terms. He claims that it is nonsensical to say that the whole array
object is nonmodifiable, but individual elements contained therein are
modifiable.

That's about it really. So, if you want to argue with Paul, try to
explain slowly and in great detail how the whole array object can be
called "not modifiable", but the individual contained array elements
can be modifiable. As far as I can tell, that's the basis of his
misunderstanding.
 
I

Ian Collins

A pointer in assembly is anything that is being used to store an address
and a constant being used as a stack frame pointer offset is not
something which is being used to store an address; such a constant is
only being used to emit machine code in the text segment.

Be careful Leigh, you may have noticed that my delusion as to what is
and isn't a pointer in assembly has been shattered by our good friend
Paul. It's really troubling to realise I have to go back and review
over 30 years of assembly listings and check all the places I thought I
was returning pointers and updated them to use -20.

Should I notify my past clients? Will the avionics applications using
my custom x86 allocator stop working now this delusion has been
shattered? Will reality ever be the same again?

These are troubled times. Thank goodness someone had the insight to
realise -20 is the true meaning of a pointer.
 
P

Paul

OK - let's review - so we know we're on the same page:

int arr[5];

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

int *ip;

`ip' is the name of a variable that can contain the address of an `int',
it is a "pointer to int".

And:

int i;

`i' is the name of an `int'-tpe variable.

The expression:

ip=&i;

computes the address of `i', and places that value into the variable
`ip'.

This is what we've agreed to thus far... right?

--If you care, I've deciphered what Paul's on about. I don't feel like
--arguing with him, but it's painful watching you struggle as I did to
--decipher what he's rambling about.

--I'm not exactly sure of the specifics of what Paul thinks, but it's
--more or less this. Paul thinks that there are two different kinds of
--array objects. Consider:
-- int x[5];
--Paul agrees that there is a segment of memory which contains 5
--contiguous int objects. Depending on context (this is the part I
--haven't fully worked out yet), Paul also thinks that there is some
--other kind of object of array type. He thinks that this second kind of
--array object, quote unquote "array type object", contains merely a
--pointer to the first int object of the 5 int contiguous int objects.
--He thinks that this pointer occupies a distinct and separate piece of
--memory from the 5 contiguous int objects. He thinks that the terms
--"array object" and "object of array type" do not refer to the region
--of memory of the 5 contiguous int objects.

--His reason for believing so is one part of the C++ standard which
--mentions that array objects are not modifiable.

No you are incorrect. My opinion that the object 'arr' and the 5 contiguous
integer objects are different entites is bases on the fact that they contain
contain different values.

in the following code:
int arr[5]={0};
std::cout<< arr;
std::cout<< arr[0];

The value accessed by arr is not any value that is stored within the 5
contiguous integer objects.
If 'arr' was truly the same as the 5 integer objects then it would store the
same value.

The fact that the standard defines an object of array type to be non
modifiable, is additional information that supports my opinion about the
object 'arr' not being the same entity as the 5 integers objects. This
supports my view because the 5 integer objects are modifiable and 'arr'
isn't, and the as the same object cannot be both modifiable and also
non-modifiable they must be different objects.


-- As I've tried to
--explain to him, the individual array element sub-objects are
--modifiable, but the array object is not modifiable.

This does not make sense according to you definition of an array object
being the contiguous elements. If the elements are modified then the block
of memory that contains these elements is aslo modified.

--What that means is
--that the individual elements, if of built-in type, may appear on the
--left hand side of a built in assignment operator, but expressions of
--array type may not appear on the left hand side of the build in
--assignment operator. It's a statement about lvalues and rvalues and
--the C++ type system, not of any sort of restrictions on writes to the
--array elements or whatever. Paul thinks that this is a contradiction
--in terms. He claims that it is nonsensical to say that the whole array
--object is nonmodifiable, but individual elements contained therein are
--modifiable.

An object cannot be modifiable and non-modifiable at the same time. It is
either one or the other.
If one object is modifiable and another is non-modifiable then they must be
different objects.


--That's about it really. So, if you want to argue with Paul, try to
--explain slowly and in great detail how the whole array object can be
--called "not modifiable", but the individual contained array elements
--can be modifiable. As far as I can tell, that's the basis of his
--misunderstanding.

An object is a region of storage , right?
If that region of storage is non modifiable , it cannot be modified. You
cannot define a region of storage non-modifiable, yet also define it as
modifiable at the same time , this is nonsensical.
 
P

Paul

Leigh Johnston said:
Leigh Johnston said:
On 28/05/2011 00:40, Paul wrote:


[snip]

It is an integer constant representing an offset to be applied to a
stack frame pointer; it is NOT a pointer for any definition of
"pointer"; it is like saying 'foo' below is a C++ pointer because we
add it to a C++ pointer:

const std::size_t foo = 42;
int *p = ...;
int *p2 = p + foo; // is foo a pointer? don't be stupid.

No incorrect , you said it was not a pointer in assembly language.
Ovbioustly its not a C++ pointer, its an array type object.

Do you not understand the meaning of the words "it is like"? Do you
know what an "analogy" is? Have you ever bothered to try "lateral
thinking"?

I never said it was a C++ pointer; I was giving you a C++ analogy of
why a pointer offset (for any definition of "pointer") is not a pointer.
But a pointer in assembly is not the same as a pointer in C++. A pointer
in C++ is a pointer type object, or an object of pointer type.
Assembly does not have types, a pointer in assembly is the same as any
other variable or constant, except that its intended use is to store an
address(or an offset) to another memory location.

I gave you an analogy; you obviously do not understand analogies. An
analogy explains one thing by comparing it to something else and these two
things are *similar* in some respect not the *same*.
You cannot compare an elephants ability to lift objects with its trunk to
that of an ant, because an ant doesn't have a trunk.
Likewise you cannot compare a C++ type, to an assembler variable or constant
because assembler doesn't have types.
Get a clue.

A pointer in assembly is anything that is being used to store an address
and a constant being used as a stack frame pointer offset is not something
which is being used to store an address; such a constant is only being
used to emit machine code in the text segment.
No you are wrong a pointer is assembly does not necessarily store a real
address, a variable that stores an offset or an index is also considered a
pointer in assembly language.
I refer you to section 5.5 Pointer data types in the following link:
http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_5/CH05-1.html#HEADING1-197
 
P

Paul

Ian Collins said:
Be careful Leigh, you may have noticed that my delusion as to what is and
isn't a pointer in assembly has been shattered by our good friend Paul.
It's really troubling to realise I have to go back and review over 30
years of assembly listings and check all the places I thought I was
returning pointers and updated them to use -20.

Should I notify my past clients? Will the avionics applications using my
custom x86 allocator stop working now this delusion has been shattered?
Will reality ever be the same again?

These are troubled times. Thank goodness someone had the insight to
realise -20 is the true meaning of a pointer.

--
You are very quick to dismiss my opinion of what a pointer is in assembly as
incorrect but what exactly is your opinion of what a pointer is?

What is a pointer in assembly, in your opinion?
I put this question to both you and Leigh.
 
I

Ian Collins

You are very quick to dismiss my opinion of what a pointer is in assembly as
incorrect but what exactly is your opinion of what a pointer is?

I was equally quick to dismiss the prediction that the world would end
last weekend.

A pointer in x86 assembly is simply a memory location or register that
contains the address of another memory location. That's is not my
opinion, it is what it is.

The pointers in your example are esp (the stack pointer) and ebp (the
base pointer).

The instruction

mov DWORD PTR _arr$[ebp], 0

given the definition of the constant _arr$

_arr$ = -12 ; size = 12

writes zero the the memory location who's address is ebp-12. Here ebp
is the pointer and -12 is the offset.

The next assignment which is a bit messy in MASM,

mov DWORD PTR _arr$[ebp+4], eax

writes zero the the memory location who's address is ebp-12+4.

The GNU assemble output is somewhat clearer:

movl $0, -12(%ebp)
movl $0, -8(%ebp)

The pointer+offset relation is the same is in C or C++ when we write

int* p = arr;
*(p+1) = 0;

The '1' above is no more a pointer than the -12 in the assembly.
 
P

Paul

Ian Collins said:
I was equally quick to dismiss the prediction that the world would end
last weekend.

A pointer in x86 assembly is simply a memory location or register that
contains the address of another memory location. That's is not my
opinion, it is what it is.

No that is your opinion.
Other people have different opinions and I happen to be one of those people.
I have already posted a link to Randal Hydes Art of Assembly that describes
what a pointer is, and RH defines that a pointer can be a simple offset.
Here is another link that shows some other peoples opinions:
http://stackoverflow.com/questions/5055619/pointers-seen-on-assembly-or-registries


The pointers in your example are esp (the stack pointer) and ebp (the base
pointer).

These are hardware registers.
The instruction

mov DWORD PTR _arr$[ebp], 0

given the definition of the constant _arr$

_arr$ = -12 ; size = 12

writes zero the the memory location who's address is ebp-12. Here ebp is
the pointer and -12 is the offset.

_arr$ is a label that equates to the value of (-12) .
Here the label _arr$ is used as a pointer,


The next assignment which is a bit messy in MASM,

mov DWORD PTR _arr$[ebp+4], eax

writes zero the the memory location who's address is ebp-12+4.

This confirms that _arr$ is an offset, which is used to create a memory
address. Therefore it's a pointer.
The GNU assemble output is somewhat clearer:

movl $0, -12(%ebp)
movl $0, -8(%ebp)

The pointer+offset relation is the same is in C or C++ when we write

int* p = arr;
*(p+1) = 0;

The '1' above is no more a pointer than the -12 in the assembly.

--
Why are you trying to comapre a C++ pointer to that of an asm pointer?
The concept of a pointer in C++ does not exist in asm, in C++ a pointer is
an object with a pointer type.

Given the C++ code :

int x=0;
int main(){
int* p1= &x;
}

The following asm is produced.:
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC ?x@@3HA ; x
_BSS SEGMENT
?x@@3HA DD 01H DUP (?) ; x
_BSS ENDS
PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
_p1$ = -4 ; size = 4
/******************************/
The line above shows that p1 is created in asm as simply a label whos value
is an offset.
/*****************************/

_main PROC
; File c:\cpp\public.cpp
; Line 6
push ebp
mov ebp, esp
push ecx
; Line 7
mov DWORD PTR _p1$[ebp], OFFSET ?x@@3HA ; x
; Line 8
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END
 
P

Paul

Leigh Johnston said:
Leigh Johnston said:
On 28/05/2011 01:32, Paul wrote:

On 28/05/2011 00:40, Paul wrote:


[snip]

It is an integer constant representing an offset to be applied to a
stack frame pointer; it is NOT a pointer for any definition of
"pointer"; it is like saying 'foo' below is a C++ pointer because we
add it to a C++ pointer:

const std::size_t foo = 42;
int *p = ...;
int *p2 = p + foo; // is foo a pointer? don't be stupid.

No incorrect , you said it was not a pointer in assembly language.
Ovbioustly its not a C++ pointer, its an array type object.

Do you not understand the meaning of the words "it is like"? Do you
know what an "analogy" is? Have you ever bothered to try "lateral
thinking"?

I never said it was a C++ pointer; I was giving you a C++ analogy of
why a pointer offset (for any definition of "pointer") is not a
pointer.

But a pointer in assembly is not the same as a pointer in C++. A
pointer
in C++ is a pointer type object, or an object of pointer type.
Assembly does not have types, a pointer in assembly is the same as any
other variable or constant, except that its intended use is to store an
address(or an offset) to another memory location.

I gave you an analogy; you obviously do not understand analogies. An
analogy explains one thing by comparing it to something else and these
two things are *similar* in some respect not the *same*.
You cannot compare an elephants ability to lift objects with its trunk
to that of an ant, because an ant doesn't have a trunk.
Likewise you cannot compare a C++ type, to an assembler variable or
constant because assembler doesn't have types.

You still do not understand what an analogy is. Fail.
No you are wrong a pointer is assembly does not necessarily store a real
address, a variable that stores an offset or an index is also considered
a pointer in assembly language.

No it isn't; see Ian Collins' reply which agrees with what I have been
saying with much clarity.

Again you are confusing two different terms with the same name: an Intel
x86 segment offset is not the same as an offset used in conjunction with a
pointer (or address).

I never even mentioned segment offsets. You are the one who seems confused.

Read decent computer science books not ancient (i.e. mostly irrelevant)
x86 online asm tutorials.

I just posted a link to one, why don't you read it.
 
P

Paul

Leigh Johnston said:
[snip]

It is an integer constant representing an offset to be applied to
a
stack frame pointer; it is NOT a pointer for any definition of
"pointer"; it is like saying 'foo' below is a C++ pointer
because we
add it to a C++ pointer:

const std::size_t foo = 42;
int *p = ...;
int *p2 = p + foo; // is foo a pointer? don't be stupid.

No incorrect , you said it was not a pointer in assembly language.
Ovbioustly its not a C++ pointer, its an array type object.

Do you not understand the meaning of the words "it is like"? Do you
know what an "analogy" is? Have you ever bothered to try "lateral
thinking"?

I never said it was a C++ pointer; I was giving you a C++ analogy of
why a pointer offset (for any definition of "pointer") is not a
pointer.

But a pointer in assembly is not the same as a pointer in C++. A
pointer
in C++ is a pointer type object, or an object of pointer type.
Assembly does not have types, a pointer in assembly is the same as
any
other variable or constant, except that its intended use is to
store an
address(or an offset) to another memory location.

I gave you an analogy; you obviously do not understand analogies. An
analogy explains one thing by comparing it to something else and these
two things are *similar* in some respect not the *same*.

You cannot compare an elephants ability to lift objects with its trunk
to that of an ant, because an ant doesn't have a trunk.
Likewise you cannot compare a C++ type, to an assembler variable or
constant because assembler doesn't have types.

You still do not understand what an analogy is. Fail.


Get a clue.

A pointer in assembly is anything that is being used to store an
address and a constant being used as a stack frame pointer offset is
not something which is being used to store an address; such a constant
is only being used to emit machine code in the text segment.

No you are wrong a pointer is assembly does not necessarily store a
real
address, a variable that stores an offset or an index is also
considered
a pointer in assembly language.

No it isn't; see Ian Collins' reply which agrees with what I have been
saying with much clarity.

I refer you to section 5.5 Pointer data types in the following link:
http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_5/CH05-1.html#HEADING1-197


Again you are confusing two different terms with the same name: an
Intel x86 segment offset is not the same as an offset used in
conjunction with a pointer (or address).

I never even mentioned segment offsets. You are the one who seems
confused.

The link you posted talks about x86 segment offsets so obviously one can
only conclude that that is what you are referring to when you erroneously
say an offset can be a pointer. Get a f**king clue. In x86 a segment
offset can be considered a pointer as it forms part of a logical address
but we are not talking about segment offsets; we are talking about offsets
applied to already formed logical addresses.
No the example uses segment offset addressing as an example. You are
confusing the term "offset" with this seg::eek:ffset addressing syntax.

An "offset" is an integer value which is added to another integer value to
create an address.
An "offset" can be used in many contexts and the context in which I have
been using the term "offset" is not in the context you incorrectly interpret
as seg::eek:ffset addressing.

This is also not to be confused with the asm OFFSET instruction which gets
the address of a varaible, before you try and bring that into the debate.


You posted a link to a 15 year old book on x86 assembly language
programming which is mostly irrelevant to what we are discussing.
So what if its 15 years old there are very few up to date asm books
available on the net.

The value -12 is a pointer to the array on the main stack frame.
It doesn't make any difference if it's declared as a variable i.e:

a_ptr DD -12 ;as a variable
b_ptr = -12 ;as a label.


The value -12 is an offset to to the frame pointer ebp, which results in the
address of the array.
 
T

Thomas David Rivers

The problem with this is you cannot assign to 'arr', except during
initialisation.
It's non modifiable AFAICT.

I think we need to go back to where we disagree and resolve that
before proceeding any further.
<snip>

Oh - OK - let me see if I understand.

I did take the liberty of removing the previous words, just to shorten
the posting - I hope that is OK.

When I read it, I believe you were saying that in the declartion:

int arr[5];

that 'arr' was the _name_ of the array of 5 `int' elements.

Is that correct?

If you completely agree with that, I think we can proceed from
there.

I did see some confusion regarding "compile-time" and "runtime",
which probably motivates definitions of those.

I would like to offer these definitions:

"compile-time" refers to the evaluation of the program's expression
during the compilation process. The compiler can, at its discretion,
evaluate an expression using information it can glean thru the
compilation process, or it can generate code that, when executed,
causes the execution platform to evaluate the expression.

When an expression is evaluated during execution, that is commonly
called "runtime".

Do those definition work for you?


If so, then I would offer this snippet of code as an example
of a "runtime" evaluation of the conversion from an integer
to a double:

Consider this snippet as the entire compilation unit, there
is nothing more in the input source file:

extern int i;
double foo(void)
{
double d;
d = i;
}

In this case, the compiler does not know, a-prior, the value of 'i',
and thus is obliged to produce code which will evaluate the
conversion at execution time. Therefor, following the definitions;
the conversion of 'i' from `int' to `double' is performed at runtime.

Does that sound right?

As a different example, lt's consider this:

double foo(void)
{
return 5;
}

In the C/C++ language, the expression "5" is defined to be an integer
constant.

Thus, the compiler, when processing this source, has the information
to convert the integer constant `5' (which comes from the expression "5")
to a double constant `5.0'. Thus, the compiler is not required to produce
instructions that evaluate this conversion at execution time; it can simply
use the "compile time" converted value. Note that, sometimes, the
compiler is not
obliged to use the "compile time" value (although the language standards
describe situations where it must...) so, frequently the evaluation of
expressions
at "compile time" is considered an optimization.

That is the idea I would like to follow when considering "compile time"
vs. "runtime".

Having said all of that; I'd hope these definitions of "compile time"
and "runtime"
will let us proceed with the other issues, and get back to the definitions
of arrays...

To return to that, do you agree that in this declaration:

int arr[5];

'arr' is the name of the contigous set of 5 `int' elements?

And, to go to the next step, would you agree that in this
declaration:

int i;

`i' is the name of single `int'?

- Dave Rivers -
 
P

Paul

A. Bolmarcich said:
[snip]
So what, in your mind, is the object referred to by the C++ standard as a
non modifiable object of array type?

Exactly where in the C++ standard is the phrase "non modifiable
object of array type"? I could not find it in either the 1998
standard or the 2003 revision.
Section 8.3.4 Arrays

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

Ask a Question

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

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

Ask a Question

Members online

Forum statistics

Threads
474,143
Messages
2,570,821
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top