|
|||
|
On 25/05/2011 00:12, Paul wrote:
> > "Leigh Johnston" <leigh@i42.co.uk> wrote in message > news:5cadnQfIzuppjUHQnZ2dnUVZ8kidnZ2d@giganews.com ... >> On 24/05/2011 21:04, Paul wrote: > : >>>>>>>>>>> An array object must store a pointer otherwise how does it know, >>>>>>>>>>> where >>>>>>>>>>> in memory, the array is? >>>>>>>>> Actually I should've said array *type* object. >>>>>>>>> >>>>>>>>> That is the object that stores the address when we do this: >>>>>>>>> int arr[43]; >>>>>>>>> int* pntrto_array_of_intgr_objs = arr; >>>>>>>>> >>>>>>>>> The object 'arr' must store the address of the array someplace. >>>>>>>> >>>>>>>> No it mustn't. Read my initial reply again: >>>>>>>> >>>>>>> Yes it must how can we do this : >>>>>>> int arr[6]; >>>>>>> int* p = arr; >>>>>>> >>>>>>> arr must hold the address of the array or how can it be convered >>>>>>> to a >>>>>>> pointer? >>>>>> >>>>>> Wrong; arr does not hold the address of the array; arr *is* the >>>>>> array. >>>>>> >>>>>>> Do you think this value is plucked out of thin air? >>>>>> >>>>>> The compiler knows the address of the array relative to something >>>>>> else >>>>>> (such as a stack frame pointer or a 'this' pointer). Again if you >>>>>> want >>>>>> something that holds the address of the array then you want a pointer >>>>>> to an array (as I said above). >>>>> >>>>> What you say doesn't make sense. You say the compiler KNOWS the >>>>> address >>>>> of the array(whether it be a relative address or otherwise is >>>>> irrelevant). >>>>> How does it KNOW this address? It cannot KNOW this address unless it >>>>> stores it someplace. >>>> >>>> What I said makes perfect sense if you are not dense. The address is >>>> calculated using an offset to something else (such as a stack frame >>>> pointer or a 'this' pointer). For example for an array on the stack >>>> the compiler KNOWS that array element n is located at stack frame >>>> pointer + o bytes; if n is a constant then o can be a constant known >>>> at compile time; if n is not a constant then all we need is a simple >>>> effective address calculation involving the stack frame pointer, n and >>>> the sizeof an element to determine the address of element n. >>>> >>> The address cannot be calculated with random numbers. The address must >>> be known, whether it is known as an offset or a real address is >>> irrelevant. >>> This known address must be stored in an object someplace. >>> >>>>> >>>>> So where is this address stored and how does the compiler know >>>>> where to >>>>> find this stored address, if arr does not store it? >>>> >>>> There is no address stored; there is no difference between how the >>>> address of an array object is calculated and how the address of any >>>> other kind of object is calculated: there is nothing special about >>>> arrays. The address of an array or an array element is calculated at >>>> runtime using an effective address calculation involving some other >>>> pointer (stack frame pointer or a 'this' pointer). >>> >>> It doesn't matter if it is an offset or a real address, the offset value >>> must be stored to be known, it cannot just be magically KNOWN by the >>> compiler. >> >> Asserting falsehoods just makes you look dense. The offset can be >> "stored" in the text segment. R E A D A B O O K . >> > > Its an object stored in memory regardless of what segment it is stored in. > An offset is not an object; an offset can be embedded in the machine code in the text segment where it is used to calculate the address of an object when added to some other pointer such as a stack frame pointer or a 'this' pointer. S T O P B E I N G O B T U S E . R E A D A B O O K . /Leigh |
|
|
||||
|
||||
|
|
|
|||
|
On May 24, 2:23*pm, "Paul" <pchris...@yahoo.co.uk> wrote:
> "Ian Collins" <ian-n...@hotmail.com> wrote in message > > Now here's the big one: > > > If there is an object that stores the address, where is the address of > > that object stored? > > Yes thats about as big as your cock, and that's not very big at all. > ![]() Ok. A good legitimate question, and he entirely avoids it. He has to be a troll, or he's so hopelessly gone. Either way, I feel bad now about replying in such detail to him recently. I would just feel bad if someone else came along and read this, thinking that Paul knows what he's talking about. Duty Calls http://xkcd.com/386/ Ugg. This is supposed to be a useful resource for others, right? Suppose I'll have to strike the right balance. Correct him once a thread if he doesn't spam, and ignore him when he does spam. |
|
|||
|
"Joshua Maurice" <joshuamaurice@gmail.com> wrote in message news:35b6e7dd-dfe1-4e71-bd6c-e043adb79538@35g2000prp.googlegroups.com... On May 24, 2:23 pm, "Paul" <pchris...@yahoo.co.uk> wrote: > "Ian Collins" <ian-n...@hotmail.com> wrote in message > > Now here's the big one: > > > If there is an object that stores the address, where is the address of > > that object stored? > > Yes thats about as big as your cock, and that's not very big at all. > ![]() --Ok. A good legitimate question, and he entirely avoids it. He has to --be a troll, or he's so hopelessly gone. Either way, I feel bad now --about replying in such detail to him recently. I would just feel bad --if someone else came along and read this, thinking that Paul knows --what he's talking about. If you think this is a legitimate point please raise it in the new thread and I will address it. This is a place where you can hide so why are you discussing here when there is a new thread that directly addresses this point? |
|
|||
|
Alf P. Steinbach /Usenet wrote:
> > 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 - -- rivers@dignus.com Work: (919) 676-0847 Get your mainframe programming tools at http://www.dignus.com |
|
|||
|
Paul wrote:
> > 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. > >> >> In that sense; the hardware register is the container that the generated >> code employs to implement the expression... but, there's not a C++ >> "object" >> for it... it's just how the expression is compiled. >> > Got nothing to do with hardware registers really. Its more to do with > terminology and peoples understanding. 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 - -- rivers@dignus.com Work: (919) 676-0847 Get your mainframe programming tools at http://www.dignus.com |
|
|||
|
"Paul" <pchristor@yahoo.co.uk> ha scritto nel messaggio news:bHACp.25543$IL2.14423@newsfe04.ams2... > > "A. Bolmarcich" <aggedor@earl-grey.cloud9.net> wrote in message #include <stdio.h> #include <stdlib.h> #include <iostream.h> int main(void) {int arr[3] = {1,2,3}, arr1[3] = {4,5,6}; int *parr = arr; int (*pparr)[3] = &arr; printf("arr=%p a[0]=%d a[1]=%d a[2]=%d\n", arr, arr[0], arr[1], arr[2]); std::cout<< "*parr=" << *parr << "\n"; //outputs 1 because it points to the first element of the array. std::cout<< "*pparr=" << *pparr << "\n"; *parr=*arr1; printf("arr=%p a[0]=%d a[1]=%d a[2]=%d\n", arr, arr[0], arr[1], arr[2]); //outputs a memory address because it points to an array-type object. return 0; } here print arr=0012FF5C a[0]=1 a[1]=2 a[2]=3 *parr=1 *pparr=12ff5c arr=0012FF5C a[0]=4 a[1]=2 a[2]=3 this "*parr=*arr1;" change only the first int what follow (*pparr)[3] for copy is a pointer to int and not a pointer to 3 ints arr1 for copy is a pointer to int and not a pointer to 3 ints for copy pparr and arr dacay to a pointer to int? yes |
|
|||
|
On 2011-05-23, Paul <pchristor@yahoo.co.uk> wrote:
> > "A. Bolmarcich" <aggedor@earl-grey.cloud9.net> wrote in message > news:slrnitlb8j.1ruu.aggedor@earl-grey.cloud9.net... >> On 2011-05-20, Paul <pchristor@yahoo.co.uk> wrote: >>> >>> "A. Bolmarcich" <aggedor@earl-grey.cloud9.net> wrote in message >>> news:slrnitans0.14gr.aggedor@earl-grey.cloud9.net... >>>> On 2011-05-18, Paul <pchristor@yahoo.co.uk> wrote: [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? 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....0cdfc958?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) 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. [snip] >> Avoiding the term "array-type" that you use but the C++ standard >> doesn't: the object pointed to by pparr is an array. The type of >> the object pointed to is an array of int. As with all arrays in C++, >> in some contexts, array-to-pointer conversion is implicitly applied >> and the result of the conversion is a pointer to the first element of >> the array. >> > No the C++ standard states its an array type object. > > The object pointed to is an array TYPE. 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. |
|
|||
|
"A. Bolmarcich" <aggedor@earl-grey.cloud9.net> wrote in message news:slrnitqfvi.10rf.aggedor@earl-grey.cloud9.net... > [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....0cdfc958?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] > >>> Avoiding the term "array-type" that you use but the C++ standard >>> doesn't: the object pointed to by pparr is an array. The type of >>> the object pointed to is an array of int. As with all arrays in C++, >>> in some contexts, array-to-pointer conversion is implicitly applied >>> and the result of the conversion is a pointer to the first element of >>> the array. >>> >> No the C++ standard states its an array type object. >> >> The object pointed to is an array TYPE. > > 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. |
|
|||
|
"Thomas David Rivers" <rivers@dignus.com> wrote in message news:4DDD34A8.6030005@dignus.com... > Paul wrote: > >> >> 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. > 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. > > > >> >>> >>> In that sense; the hardware register is the container that the generated >>> code employs to implement the expression... but, there's not a C++ >>> "object" >>> for it... it's just how the expression is compiled. >>> >> Got nothing to do with hardware registers really. Its more to do with >> terminology and peoples understanding. > > > 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. |
|
|||
|
On May 25, 4:06*am, gwowen <gwo...@gmail.com> wrote:
> On May 25, 1:01*am, Joshua Maurice <joshuamaur...@gmail.com> wrote: > > > Ok. A good legitimate question, and he entirely avoids it. He has to > > be a troll, or he's so hopelessly gone. > > How astute you are! I'm naive and have too much hope sometimes. Sorry. |
|
|||
|
On 25/05/2011 21:04, Paul wrote:
> > "A. Bolmarcich" <aggedor@earl-grey.cloud9.net> wrote in message > news:slrnitqfvi.10rf.aggedor@earl-grey.cloud9.net... >> [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....0cdfc958?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. > > >> >> 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] >> >>>> Avoiding the term "array-type" that you use but the C++ standard >>>> doesn't: the object pointed to by pparr is an array. The type of >>>> the object pointed to is an array of int. As with all arrays in C++, >>>> in some contexts, array-to-pointer conversion is implicitly applied >>>> and the result of the conversion is a pointer to the first element of >>>> the array. >>>> >>> No the C++ standard states its an array type object. >>> >>> The object pointed to is an array TYPE. >> >> 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. As I have already told you else-thread it is not an object; it is not a pointer object; it is an *offset* embedded in the text segment; thanks for proving me correct and yourself incorrect. > > 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. It is not an "array type object"; it is an offset use to calculate the address of the array of array element relative to the stack frame pointer. HTH. /Leigh |
|
|||
|
On 05/26/11 08:04 AM, Paul wrote:
> > 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. -- Ian Collins |
|
|||
|
Paul wrote:
> > "Thomas David Rivers" <rivers@dignus.com> wrote in message > news:4DDD34A8.6030005@dignus.com... > >> Paul wrote: >> >>> >>> An array object is not the same as a single variable. >> >> >> >> Well - this is likely a mistake.. but.... >> >> >> >> 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. 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 - -- rivers@dignus.com Work: (919) 676-0847 Get your mainframe programming tools at http://www.dignus.com |
|
|||
|
"Thomas David Rivers" <rivers@dignus.com> wrote in message news:4DDD9893.9060502@dignus.com... > Paul wrote: > >> >> "Thomas David Rivers" <rivers@dignus.com> wrote in message >> news:4DDD34A8.6030005@dignus.com... >> >>> Paul wrote: >>> >>>> >>>> An array object is not the same as a single variable. >>> >>> >>> >>> Well - this is likely a mistake.. but.... >>> >>> >>> >>> 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. > > > 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> |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|