* Address of an object @ 2006-09-15 20:24 Dmitry A. Kazakov 2006-09-15 23:31 ` Adam Beneschan 2006-09-16 13:21 ` Stephen Leake 0 siblings, 2 replies; 12+ messages in thread From: Dmitry A. Kazakov @ 2006-09-15 20:24 UTC (permalink / raw) Both X'Address and Unchecked_Conversion of a pointer to X would not give the true address of X (i.e. the address returned by Allocate of the corresponding storage pool). For an array type, X'Address is the address of the first element, the dope is out. Is there any better way than this extremely ugly and slow: type Fake_Pool is new Root_Storage_Pool with record Location : Address; end record; procedure Allocate (...) is -- Never called begin raise Program_Error; end Allocate; procedure Deallocate ( Pool : in out Fake_Pool; Storage_Address : in Address; Size : Storage_Count; Alignment : Storage_Count ) is begin Pool.Location := Storage_Address; end Deallocate; function Storage_Size (Pool : Fake_Pool) -- Never called return Storage_Count is begin return 0; end Storage_Size; function Address_Of (Pointer : Object_Ptr) return Address is Pool : Fake_Pool; -- A controlled object, that must be slow! type Fake_Ptr is access Object_Type; for Fake_Ptr'Storage_Pool use Pool; function To_Fake is new Ada.Unchecked_Conversion (Object_Ptr, Fake_Ptr); procedure Free is new Ada.Unchecked_Deallocation (Object_Type, Fake_Ptr); Ptr : Fake_Ptr := To_Fake (Pointer); begin Free (Ptr); return Pool.Location; end Address_Of; ? -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Address of an object 2006-09-15 20:24 Address of an object Dmitry A. Kazakov @ 2006-09-15 23:31 ` Adam Beneschan 2006-09-16 8:13 ` Dmitry A. Kazakov 2006-09-16 13:21 ` Stephen Leake 1 sibling, 1 reply; 12+ messages in thread From: Adam Beneschan @ 2006-09-15 23:31 UTC (permalink / raw) Dmitry A. Kazakov wrote: > Both X'Address and Unchecked_Conversion of a pointer to X would not give > the true address of X (i.e. the address returned by Allocate of the > corresponding storage pool). For an array type, X'Address is the address of > the first element, the dope is out. > > Is there any better way than this extremely ugly and slow: > > type Fake_Pool is new Root_Storage_Pool with record > Location : Address; > end record; > > procedure Allocate (...) is -- Never called > begin > raise Program_Error; > end Allocate; > > procedure Deallocate > ( Pool : in out Fake_Pool; > Storage_Address : in Address; > Size : Storage_Count; > Alignment : Storage_Count > ) is > begin > Pool.Location := Storage_Address; > end Deallocate; > > function Storage_Size (Pool : Fake_Pool) -- Never called > return Storage_Count is > begin > return 0; > end Storage_Size; > > function Address_Of (Pointer : Object_Ptr) return Address is > Pool : Fake_Pool; -- A controlled object, that must be slow! > type Fake_Ptr is access Object_Type; > for Fake_Ptr'Storage_Pool use Pool; > function To_Fake is > new Ada.Unchecked_Conversion (Object_Ptr, Fake_Ptr); > procedure Free is > new Ada.Unchecked_Deallocation (Object_Type, Fake_Ptr); > Ptr : Fake_Ptr := To_Fake (Pointer); > begin > Free (Ptr); > return Pool.Location; > end Address_Of; > > ? This sounds highly implementation-dependent. I don't know what an Object_Ptr points to; but if it points to something that could be represented, in some implementations, as discontiguous data, then the above won't necessarily work---calling the instance of Unchecked_Deallocation could well cause the storage pool Deallocate routine to be called more than once. And then your result will be whatever was passed to the last Deallocate call, which may or may not be meaningful. I don't think there's an implementation-independent way to get what you're looking for (and, frankly, I'm not even sure there's an implementation-independent way to *define* what you're looking for). Assuming that you're interested in only one implementation, perhaps you can ask the implementors to provide an implementation-dependent attribute or something to give you what you need. -- Adam ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Address of an object 2006-09-15 23:31 ` Adam Beneschan @ 2006-09-16 8:13 ` Dmitry A. Kazakov 2006-09-18 10:29 ` Stephen Leake 0 siblings, 1 reply; 12+ messages in thread From: Dmitry A. Kazakov @ 2006-09-16 8:13 UTC (permalink / raw) On 15 Sep 2006 16:31:54 -0700, Adam Beneschan wrote: > Dmitry A. Kazakov wrote: >> Both X'Address and Unchecked_Conversion of a pointer to X would not give >> the true address of X (i.e. the address returned by Allocate of the >> corresponding storage pool). For an array type, X'Address is the address of >> the first element, the dope is out. >> >> Is there any better way than this extremely ugly and slow: >> >> type Fake_Pool is new Root_Storage_Pool with record >> Location : Address; >> end record; >> >> procedure Allocate (...) is -- Never called >> begin >> raise Program_Error; >> end Allocate; >> >> procedure Deallocate >> ( Pool : in out Fake_Pool; >> Storage_Address : in Address; >> Size : Storage_Count; >> Alignment : Storage_Count >> ) is >> begin >> Pool.Location := Storage_Address; >> end Deallocate; >> >> function Storage_Size (Pool : Fake_Pool) -- Never called >> return Storage_Count is >> begin >> return 0; >> end Storage_Size; >> >> function Address_Of (Pointer : Object_Ptr) return Address is >> Pool : Fake_Pool; -- A controlled object, that must be slow! >> type Fake_Ptr is access Object_Type; >> for Fake_Ptr'Storage_Pool use Pool; >> function To_Fake is >> new Ada.Unchecked_Conversion (Object_Ptr, Fake_Ptr); >> procedure Free is >> new Ada.Unchecked_Deallocation (Object_Type, Fake_Ptr); >> Ptr : Fake_Ptr := To_Fake (Pointer); >> begin >> Free (Ptr); >> return Pool.Location; >> end Address_Of; >> >> ? > > This sounds highly implementation-dependent. At best! > I don't think there's an implementation-independent way to get what > you're looking for (and, frankly, I'm not even sure there's an > implementation-independent way to *define* what you're looking for). > Assuming that you're interested in only one implementation, perhaps you > can ask the implementors to provide an implementation-dependent > attribute or something to give you what you need. Hmm, actually it is quite easy to define formally: Let P be a pointer to X. Then what I need is the address A, which the pool P'Storage_Pool returned when X was allocated there. This is the same address the pool will receive upon freeing X. ---------- The problem behind. What I need is to be able to add some dopes to the objects allocated in *my* pool. new T calls to the pool's Allocate, but the address it returns gets mangled by the compiler, when converted to the pointer P [for example, when T is String]. So, having P I cannot get at my dope. Its address should be A = P.all'Address - Offs where Offs is known, alas, to the compiler only. The compiler must know that, otherwise it couldn't pass that to Deallocate. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Address of an object 2006-09-16 8:13 ` Dmitry A. Kazakov @ 2006-09-18 10:29 ` Stephen Leake 2006-09-18 12:09 ` Dmitry A. Kazakov 0 siblings, 1 reply; 12+ messages in thread From: Stephen Leake @ 2006-09-18 10:29 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > Let P be a pointer to X. Then what I need is the address A, which the pool > P'Storage_Pool returned when X was allocated there. This is the same > address the pool will receive upon freeing X. > > ---------- > The problem behind. What I need is to be able to add some dopes to the > objects allocated in *my* pool. new T calls to the pool's Allocate, but the > address it returns gets mangled by the compiler, when converted to the > pointer P [for example, when T is String]. So, having P I cannot get at my > dope. Its address should be > > A = P.all'Address - Offs > > where Offs is known, alas, to the compiler only. The compiler must know > that, otherwise it couldn't pass that to Deallocate. So you want access to some compiler-dependent information; clearly the method will be compiler-dependent, since it isn't defined by the language. What are you going to do with the "dopes" you add? They won't be visible from Ada. -- -- Stephe ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Address of an object 2006-09-18 10:29 ` Stephen Leake @ 2006-09-18 12:09 ` Dmitry A. Kazakov 2006-09-18 13:54 ` Maciej Sobczak 2006-09-19 9:15 ` Stephen Leake 0 siblings, 2 replies; 12+ messages in thread From: Dmitry A. Kazakov @ 2006-09-18 12:09 UTC (permalink / raw) On Mon, 18 Sep 2006 06:29:24 -0400, Stephen Leake wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > >> Let P be a pointer to X. Then what I need is the address A, which the pool >> P'Storage_Pool returned when X was allocated there. This is the same >> address the pool will receive upon freeing X. >> >> ---------- >> The problem behind. What I need is to be able to add some dopes to the >> objects allocated in *my* pool. new T calls to the pool's Allocate, but the >> address it returns gets mangled by the compiler, when converted to the >> pointer P [for example, when T is String]. So, having P I cannot get at my >> dope. Its address should be >> >> A = P.all'Address - Offs >> >> where Offs is known, alas, to the compiler only. The compiler must know >> that, otherwise it couldn't pass that to Deallocate. > > So you want access to some compiler-dependent information; clearly the > method will be compiler-dependent, since it isn't defined by the language. No, I don't want to access it. I only want my information. > What are you going to do with the "dopes" you add? They won't be > visible from Ada. That's exactly the goal, because what I want is to extend types in a way Ada does not support. I wanted to add something to a type without quarreling with Ada, which mistakenly [OK, that was a political decision] does not support MI. It was corrected in Ada 2005 but only for pure interfaces, while I need implementations. There is a vast number of cases where it might be useful. It seemed quite easy, thank to user-defined pools. Well, actually it is spoiled a bit with pointers and generics, but that's another story. The idea is as follows: 1. You define a pool which eventually takes its memory from some another pool. 2. When something is allocated in the pool, you just add necessary data to the allocated object in front of the allocated memory block 3. The interface to this is a generic package, which provides a pointer type to the objects in the pool. [Unfortunately, the type of the pointer's pool cannot be made opaque, but that is a minor language problem.] 4. New operations are defined on the pointer type. It is clean and portable design, because all the functionality is hidden behind the pointer type. It does not break the type allocated in the pool in any way. The only unexpected problem with this is that the compiler mangles pointers and there seems to be no way to influence or learn how it does this. I would suggest to introduce a new attribute X'Pool_Address which should return the address, Unchecked_Deallocation would pass to Deallocate, but... -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Address of an object 2006-09-18 12:09 ` Dmitry A. Kazakov @ 2006-09-18 13:54 ` Maciej Sobczak 2006-09-18 14:53 ` Dmitry A. Kazakov 2006-09-19 9:15 ` Stephen Leake 1 sibling, 1 reply; 12+ messages in thread From: Maciej Sobczak @ 2006-09-18 13:54 UTC (permalink / raw) Dmitry A. Kazakov wrote: > I wanted to add something to a type without > quarreling with Ada, which mistakenly [OK, that was a political decision] > does not support MI. You might consider doing it in C++ instead. Because - you know - *fighting with the language* can only increase the probability of introducing bugs and in the end increase the total cost of software production, not mentioning its maintenance. (Sorry, could not resist. ;-) ) -- Maciej Sobczak : http://www.msobczak.com/ Programming : http://www.msobczak.com/prog/ ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Address of an object 2006-09-18 13:54 ` Maciej Sobczak @ 2006-09-18 14:53 ` Dmitry A. Kazakov 0 siblings, 0 replies; 12+ messages in thread From: Dmitry A. Kazakov @ 2006-09-18 14:53 UTC (permalink / raw) On Mon, 18 Sep 2006 15:54:30 +0200, Maciej Sobczak wrote: > Dmitry A. Kazakov wrote: > >> I wanted to add something to a type without >> quarreling with Ada, which mistakenly [OK, that was a political decision] >> does not support MI. > > You might consider doing it in C++ instead. Actually, I did. It was long ago. OK, there were other problems with that in C++. But for all, the project is in Ada. > Because - you know - *fighting with the language* can only increase the > probability of introducing bugs and in the end increase the total cost > of software production, not mentioning its maintenance. That's true. But we should consider all causes where we are forced to fight with the language. And the problem with C++ is that it is almost impossible to cut a clean design of anything by an inch more complex than hello-world... -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Address of an object 2006-09-18 12:09 ` Dmitry A. Kazakov 2006-09-18 13:54 ` Maciej Sobczak @ 2006-09-19 9:15 ` Stephen Leake 2006-09-19 13:29 ` Dmitry A. Kazakov 1 sibling, 1 reply; 12+ messages in thread From: Stephen Leake @ 2006-09-19 9:15 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: >> So you want access to some compiler-dependent information; clearly the >> method will be compiler-dependent, since it isn't defined by the language. > > No, I don't want to access it. I only want my information. I don't understand. You want write-only data? >> What are you going to do with the "dopes" you add? They won't be >> visible from Ada. > > That's exactly the goal, because what I want is to extend types in a way > Ada does not support. I wanted to add something to a type without > quarreling with Ada, which mistakenly [OK, that was a political decision] > does not support MI. It was corrected in Ada 2005 but only for pure > interfaces, while I need implementations. There is a vast number of cases > where it might be useful. So you are trying to extend the Ada language. You should be editing the compiler; that's one of the reasons GNAT is open source. > It seemed quite easy, thank to user-defined pools. Well, actually it is > spoiled a bit with pointers and generics, but that's another story. Actually, that's part of the reason MI isn't in Ada. You must consider how it impacts the entire language. > The idea is as follows: > > 1. You define a pool which eventually takes its memory from some another > pool. > > 2. When something is allocated in the pool, you just add necessary data to > the allocated object in front of the allocated memory block > > 3. The interface to this is a generic package, which provides a pointer > type to the objects in the pool. [Unfortunately, the type of the pointer's > pool cannot be made opaque, but that is a minor language problem.] So this generic package needs to read the data, from Ada. Or at least provide a pointer to it, so other Ada packages can read it. > 4. New operations are defined on the pointer type. In Ada, or some other language? > It is clean and portable design, because all the functionality is hidden > behind the pointer type. It does not break the type allocated in the pool > in any way. > > The only unexpected problem with this is that the compiler mangles pointers > and there seems to be no way to influence or learn how it does this. Read the source code for the compiler. Or ask the compiler vendor. -- -- Stephe ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Address of an object 2006-09-19 9:15 ` Stephen Leake @ 2006-09-19 13:29 ` Dmitry A. Kazakov 0 siblings, 0 replies; 12+ messages in thread From: Dmitry A. Kazakov @ 2006-09-19 13:29 UTC (permalink / raw) On Tue, 19 Sep 2006 05:15:01 -0400, Stephen Leake wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > >>> So you want access to some compiler-dependent information; clearly the >>> method will be compiler-dependent, since it isn't defined by the language. >> >> No, I don't want to access it. I only want my information. > > I don't understand. You want write-only data? No, I just don't care about them. As an example consider a container library or a garbage collector. They don't care about handling the data. >>> What are you going to do with the "dopes" you add? They won't be >>> visible from Ada. >> >> That's exactly the goal, because what I want is to extend types in a way >> Ada does not support. I wanted to add something to a type without >> quarreling with Ada, which mistakenly [OK, that was a political decision] >> does not support MI. It was corrected in Ada 2005 but only for pure >> interfaces, while I need implementations. There is a vast number of cases >> where it might be useful. > > So you are trying to extend the Ada language. You should be editing > the compiler; that's one of the reasons GNAT is open source. GNAT is, but Ada isn't. For extending Ada there are AIs. >> It seemed quite easy, thank to user-defined pools. Well, actually it is >> spoiled a bit with pointers and generics, but that's another story. > > Actually, that's part of the reason MI isn't in Ada. You must consider > how it impacts the entire language. There cannot be any negative impact. Fundamentally, if MI is infeasible, then single inheritance must be as well. Once Ada has decided to support inheritance there is no return. >> The idea is as follows: >> >> 1. You define a pool which eventually takes its memory from some another >> pool. >> >> 2. When something is allocated in the pool, you just add necessary data to >> the allocated object in front of the allocated memory block >> >> 3. The interface to this is a generic package, which provides a pointer >> type to the objects in the pool. [Unfortunately, the type of the pointer's >> pool cannot be made opaque, but that is a minor language problem.] > > So this generic package needs to read the data, from Ada. Or at least > provide a pointer to it, so other Ada packages can read it. Sure. The pointer is a legal access type, you can do with it and through it anything, one could do in Ada. >> 4. New operations are defined on the pointer type. > > In Ada, or some other language? Of course in Ada. OK, I feel there is a need to give an example. I will start a new thread for it. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Address of an object 2006-09-15 20:24 Address of an object Dmitry A. Kazakov 2006-09-15 23:31 ` Adam Beneschan @ 2006-09-16 13:21 ` Stephen Leake 2006-09-16 17:06 ` Dmitry A. Kazakov 1 sibling, 1 reply; 12+ messages in thread From: Stephen Leake @ 2006-09-16 13:21 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > Both X'Address and Unchecked_Conversion of a pointer to X would not give > the true address of X (i.e. the address returned by Allocate of the > corresponding storage pool). For an array type, X'Address is the address of > the first element, the dope is out. > > Is there any better way A better way to do what? What are you doing, that either X'Address or X'Access is wrong? -- -- Stephe ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Address of an object 2006-09-16 13:21 ` Stephen Leake @ 2006-09-16 17:06 ` Dmitry A. Kazakov 2006-09-20 0:43 ` Randy Brukardt 0 siblings, 1 reply; 12+ messages in thread From: Dmitry A. Kazakov @ 2006-09-16 17:06 UTC (permalink / raw) On Sat, 16 Sep 2006 09:21:51 -0400, Stephen Leake wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > >> Both X'Address and Unchecked_Conversion of a pointer to X would not give >> the true address of X (i.e. the address returned by Allocate of the >> corresponding storage pool). For an array type, X'Address is the address of >> the first element, the dope is out. >> >> Is there any better way > > A better way to do what? > > What are you doing, that either X'Address or X'Access is wrong? Both are. Do the following under GNAT: type P is access String; for P'Storage_Pool use My_Pool; procedure Allocate (Pool : My_Pool; Addr : out Storage_Address; ...) is begin ... Addr := A; end Allocate; P := new String'("abc"); Then compare A with P.all'Address. They will differ. A = P.all'Address - 8, I guess. [ It is not yet another bug of GNAT, it is a proper behavior. ARM explicitly requires this.] See also my response to Adam. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Address of an object 2006-09-16 17:06 ` Dmitry A. Kazakov @ 2006-09-20 0:43 ` Randy Brukardt 0 siblings, 0 replies; 12+ messages in thread From: Randy Brukardt @ 2006-09-20 0:43 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:n03kqae9v6ah$.hjxa120hu8oq$.dlg@40tude.net... ... > type P is access String; > for P'Storage_Pool use My_Pool; > > procedure Allocate (Pool : My_Pool; Addr : out Storage_Address; ...) is > begin > ... > Addr := A; > end Allocate; > > P := new String'("abc"); > > Then compare A with P.all'Address. They will differ. A = P.all'Address - 8, > I guess. [ It is not yet another bug of GNAT, it is a proper behavior. ARM > explicitly requires this.] For what it's worth, Janus/Ada does this right (currently -- I suppose someday we might change it to match the RM, but it is unlikely -- we'd have to ban address clauses of any object with discontiguous parts, which is silly). I argued against this change to 'Address in Ada 95, but I seem to have been a minority of 1 -- so it's nice to see someone else who cares. Randy. ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2006-09-20 0:43 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2006-09-15 20:24 Address of an object Dmitry A. Kazakov 2006-09-15 23:31 ` Adam Beneschan 2006-09-16 8:13 ` Dmitry A. Kazakov 2006-09-18 10:29 ` Stephen Leake 2006-09-18 12:09 ` Dmitry A. Kazakov 2006-09-18 13:54 ` Maciej Sobczak 2006-09-18 14:53 ` Dmitry A. Kazakov 2006-09-19 9:15 ` Stephen Leake 2006-09-19 13:29 ` Dmitry A. Kazakov 2006-09-16 13:21 ` Stephen Leake 2006-09-16 17:06 ` Dmitry A. Kazakov 2006-09-20 0:43 ` Randy Brukardt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox