* Overlay allowability @ 2000-05-01 0:00 Marc A. Criley 2000-05-01 0:00 ` Ted Dennison ` (3 more replies) 0 siblings, 4 replies; 21+ messages in thread From: Marc A. Criley @ 2000-05-01 0:00 UTC (permalink / raw) A few times in my career I've encountered situations where two different representations of the same set of bits are desired in a high performance application, and this has been effected with the aid of the 'Address representation attribute. In Ada 95, an example of this would be: N : Natural; SN : Stream_Element_Array(1..N'Size / System.Storage_Unit); for SN'Address use N; This has always struck me as somewhat iffy, but I confess I've used it as well on a couple occasions with Ada 83. I've always found that it works as one intuitively expects, so long as all alignment, layout and sizing aspects are fully thought through and accommodated. So, is this within the definition of Ada 95? Or is it well-defined only for certain constructs, say scalars and non-tagged types, and dicey for others? Are there type constructs for which relying on it is clearly a reliance on undefined behavior, is the whole construct a reliance on undefined behavior? Is there a de facto, in place of a formal, expectation that this should work as expected? Marc A. Criley ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-01 0:00 Overlay allowability Marc A. Criley @ 2000-05-01 0:00 ` Ted Dennison 2000-05-03 0:00 ` Samuel T. Harris 2000-05-01 0:00 ` Tucker Taft ` (2 subsequent siblings) 3 siblings, 1 reply; 21+ messages in thread From: Ted Dennison @ 2000-05-01 0:00 UTC (permalink / raw) In article <390D94FB.D23390D4@lmco.com>, "Marc A. Criley" <marc.a.criley@lmco.com> wrote: > A few times in my career I've encountered situations where two > different representations of the same set of bits are desired in a > high > This has always struck me as somewhat iffy, but I confess I've used > it as well on a couple occasions with Ada 83. I've always found that > it works as one intuitively expects, so long as all alignment, layout > and sizing aspects are fully thought through and accommodated. In Ada 83 I believe doing that rendered your program erronious. In 95, I'm not sure, but its probably been reassigned to "bounded error" territory. This is exactly what Unchecked_Conversion was put in the language for. If performance prohibits copying the whole structure, you can always perform unchecked conversion on an access type that points to your structure (even SMART allowed this). -- T.E.D. http://www.telepath.com/~dennison/Ted/TED.html Sent via Deja.com http://www.deja.com/ Before you buy. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-01 0:00 ` Ted Dennison @ 2000-05-03 0:00 ` Samuel T. Harris 2000-05-03 0:00 ` Robert A Duff ` (2 more replies) 0 siblings, 3 replies; 21+ messages in thread From: Samuel T. Harris @ 2000-05-03 0:00 UTC (permalink / raw) Ted Dennison wrote: > > In article <390D94FB.D23390D4@lmco.com>, > "Marc A. Criley" <marc.a.criley@lmco.com> wrote: > > A few times in my career I've encountered situations where two > > different representations of the same set of bits are desired in a > > high > > > This has always struck me as somewhat iffy, but I confess I've used > > it as well on a couple occasions with Ada 83. I've always found that > > it works as one intuitively expects, so long as all alignment, layout > > and sizing aspects are fully thought through and accommodated. > > In Ada 83 I believe doing that rendered your program erronious. In 95, > I'm not sure, but its probably been reassigned to "bounded error" territory. > > This is exactly what Unchecked_Conversion was put in the language for. > If performance prohibits copying the whole structure, you can always > perform unchecked conversion on an access type that points to your > structure (even SMART allowed this). > Many times the need for such overlays is a continual need throughout a section of code. Several calls to unchecked_conversion is simply to slow and does present a consistency problem associated with having two separate objects instead of two overlayed objects. This consistency problem can be exploited in a tasking environment and cause unpredictable results. So, when performance and consistency are the requirements, make an overlay. If one simply needs to jam one kind of data into another, use unchecked_conversion. -- Samuel T. Harris, Principal Engineer Raytheon, Aerospace Engineering Services "If you can make it, We can fake it!" ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-03 0:00 ` Samuel T. Harris @ 2000-05-03 0:00 ` Robert A Duff 2000-05-03 0:00 ` Ted Dennison 2000-05-04 0:00 ` Robert Dewar 2 siblings, 0 replies; 21+ messages in thread From: Robert A Duff @ 2000-05-03 0:00 UTC (permalink / raw) "Samuel T. Harris" <samuel_t_harris@Raytheon.com> writes: > So, when performance and consistency are the requirements, > make an overlay. If one simply needs to jam one kind of data > into another, use unchecked_conversion. Ada 95 allows U_C to return its result by reference. If the compiler takes advantage of that permission, then U_C can be just as efficient as overlays. So I suggest you measure the speed before taking the above advice. - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-03 0:00 ` Samuel T. Harris 2000-05-03 0:00 ` Robert A Duff @ 2000-05-03 0:00 ` Ted Dennison 2000-05-04 0:00 ` Robert Dewar 2 siblings, 0 replies; 21+ messages in thread From: Ted Dennison @ 2000-05-03 0:00 UTC (permalink / raw) In article <3910514D.13BF2DE1@Raytheon.com>, "Samuel T. Harris" <samuel_t_harris@Raytheon.com> wrote: > Many times the need for such overlays is a continual need > throughout a section of code. Several calls to unchecked_conversion > is simply to slow and does present a consistency problem > associated with having two separate objects instead of two > overlayed objects. This consistency problem can be exploited > in a tasking environment and cause unpredictable results. Quite true. But what about unchecked-converting access types, like I was referring to? In that case, there is only *one* object, and that fact is quite clear to both the compiler and the reader. It certianly isn't significatnly slower to work this way. An optimizer might even be able to remove the extra dereferences, making the speed the same. You don't have to worry about initilization issues, as only the original object's initialzations get applied (just like one would expect). I think the tasking issue is a red herring. In a tasking environment, you have a consistency problem with *any* object (as each task may keep register copies of it). There ways to prevent or work around it in Ada of course. But I'd be very worried to add overlays into the mix. (eg: Does "pragma Atomic" work for both views of an overlaid object, or just the one?. Do synchronization points update my overlay's view of the object, if my task uses only the overlay and some other task uses only the original object? In fact, I'd be a bit worried about this whole thing in general. In Ada 83 doing this was defined as erronious. I figured that was because a chunk of code working on an object might temporarily save the object's value in a register, which would make the view from the other overlay invalid. If its safe to do that with the current version of Ada, how do Ada compilers ensure consistency between the overlaid views? -- T.E.D. http://www.telepath.com/~dennison/Ted/TED.html Sent via Deja.com http://www.deja.com/ Before you buy. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-03 0:00 ` Samuel T. Harris 2000-05-03 0:00 ` Robert A Duff 2000-05-03 0:00 ` Ted Dennison @ 2000-05-04 0:00 ` Robert Dewar 2000-05-08 0:00 ` Samuel T. Harris 2 siblings, 1 reply; 21+ messages in thread From: Robert Dewar @ 2000-05-04 0:00 UTC (permalink / raw) In article <3910514D.13BF2DE1@Raytheon.com>, "Samuel T. Harris" <samuel_t_harris@Raytheon.com> wrote: > Many times the need for such overlays is a continual need > throughout a section of code. Several calls to > unchecked_conversion > is simply to slow and does present a consistency problem > associated with having two separate objects instead of two > overlayed objects. This consistency problem can be exploited > in a tasking environment and cause unpredictable results. I think that's a potentially misleading response. It refers to an obvious misuse of unchecked conversion. The proper way to do this UC is to convert between the access types *ONCE* and then reference the view you want through the appropriate access type. This will typically give pretty much identical code to the use of an address overlay, so there is no efficiency issue. > So, when performance and consistency are the requirements, > make an overlay. If one simply needs to jam one kind of data > into another, use unchecked_conversion. This advice is to be dubious, because as above it is based on the wrong approach to using unchecked conversion. In fact, in practice in Ada 95, there is likely very little difference between the following: type a is ... type b is ... AV : aliased a; BV : aliased b; for BV'Address use AV'Address; -- your compiler may make you define a constant for this -- address making this a bit less convenient to use. and type a is ... type a_Access is access all a; type b is ... type b_Access is access all b; function To_b_Access is new UC (a_Access, b_Access); AV : aliased A; BVA : constant b_Access := To_b_Access (AV'Access); BV : B renames BVA.all; In practice, if the types are records or arrays, you can probably shorten this to: BV : constant b_Access := To_B_Access (AV'Access); and use automatic dereferencing. Which to prefer? The use of UC is to me clearer, and has the advantage of the loud "with Unchecked_Conversion" in the context clause indicating a unit that is suspect and potentially unsafe. The danger of the address overlay is that it is far too easy to sneak this in. I have even seen things like: x : integer; b : integer; for b'address use x'address; to achieve the effect of a simple renaming, and that clearly represents running amok with address overlays :-) I think I preferred the Ada 83 formulation. Sent via Deja.com http://www.deja.com/ Before you buy. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-04 0:00 ` Robert Dewar @ 2000-05-08 0:00 ` Samuel T. Harris 2000-05-08 0:00 ` Robert Dewar 0 siblings, 1 reply; 21+ messages in thread From: Samuel T. Harris @ 2000-05-08 0:00 UTC (permalink / raw) Robert Dewar wrote: > > In article <3910514D.13BF2DE1@Raytheon.com>, > "Samuel T. Harris" <samuel_t_harris@Raytheon.com> wrote: > > > Many times the need for such overlays is a continual need > > throughout a section of code. Several calls to > > unchecked_conversion > > is simply to slow and does present a consistency problem > > associated with having two separate objects instead of two > > overlayed objects. This consistency problem can be exploited > > in a tasking environment and cause unpredictable results. > > I think that's a potentially misleading response. > It refers to an obvious > misuse of unchecked conversion. The proper way to do this UC > is to convert between the access types *ONCE* and then reference > the view you want through the appropriate access type. This will > typically give pretty much identical code to the use of an > address overlay, so there is no efficiency issue. The poster wasn't asking about UCing the pointers. The question was about UCing the data vs making an overlay. UCing pointers an another way to make overlays which are IMO less clear to the reader than a address clause. Conversion of access types only works when the access types are in the same storage pool. What happens when one access type is in a user-defined storage pool and such an unchecked_conversion is performed? Better yet, what happens when both are in separate storage pools? > > > So, when performance and consistency are the requirements, > > make an overlay. If one simply needs to jam one kind of data > > into another, use unchecked_conversion. > > This advice is to be dubious, because as above > it is based on the wrong approach to using unchecked conversion. > In fact, in practice in Ada 95, there is likely very little > difference between the following: Just what is dubious about this advice. You are simpy defining two additional way to define an overlay yet you make no comment on the deciding factor! The deciding factor is the crucial part of my comment. As to the mechanics of overlays, there are many ways to achieve the desired results in Ada 95. > > type a is ... > type b is ... > > AV : aliased a; > BV : aliased b; > for BV'Address use AV'Address; > -- your compiler may make you define a constant for this > -- address making this a bit less convenient to use. I can't see why this is preferable over a straight address clause of objects of a and b. Besides, when the needs comes, often times one or the other object is already declared. Therefore AV or BV, as appropriate, will have to be setup to point to the already declared object. Seems like a lot of extra stuff when one address clause is needed. > > and > > type a is ... > type a_Access is access all a; > type b is ... > type b_Access is access all b; > > function To_b_Access is new UC (a_Access, b_Access); > > AV : aliased A; > BVA : constant b_Access := To_b_Access (AV'Access); > BV : B renames BVA.all; Also, a lot of extra stuff when a single address clause is called for. I don't see the advantage of these indirect views. Also, is a_Access and/or b_Access are allocated to user defined storage pools, then isn't this going to create problems? > > In practice, if the types are records or arrays, you can > probably shorten this to: > > BV : constant b_Access := To_B_Access (AV'Access); > > and use automatic dereferencing. > > Which to prefer? > > The use of UC is to me clearer, and has the advantage of the > loud "with Unchecked_Conversion" in the context clause > indicating a unit that is suspect and potentially unsafe. > > The danger of the address overlay is that it is far too easy > to sneak this in. I have even seen things like: > > x : integer; > b : integer; > for b'address use x'address; > > to achieve the effect of a simple renaming, and that clearly > represents running amok with address overlays :-) Yes, the above is silly! That is what code rule checkers are for. > > I think I preferred the Ada 83 formulation. Do you mean "for b use at x'address;" ? > > Sent via Deja.com http://www.deja.com/ > Before you buy. -- Samuel T. Harris, Principal Engineer Raytheon, Aerospace Engineering Services "If you can make it, We can fake it!" ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-08 0:00 ` Samuel T. Harris @ 2000-05-08 0:00 ` Robert Dewar 2000-05-09 0:00 ` Samuel T. Harris 0 siblings, 1 reply; 21+ messages in thread From: Robert Dewar @ 2000-05-08 0:00 UTC (permalink / raw) In article <3916D7F4.178B4FDE@Raytheon.com>, "Samuel T. Harris" <samuel_t_harris@Raytheon.com> wrote: > The poster wasn't asking about UCing the pointers. > The question was about UCing the data vs making an overlay. > UCing pointers an another way to make overlays which are > IMO less clear to the reader than a address clause. Well you can have any opinion you like. But unchecked conversion is far better defined than overlay. The latter is completely implementation defined, and may cause havoc due to descriptors etc. > Conversion of access types only works when the access types > are in the same storage pool. Good practice here is to use unchecked conversion only on general access pointers which do NOT reference unconstrained array types. > Just what is dubious about this advice. > You are simpy defining two additional way to define an overlay > yet you make no comment on the deciding factor! The deciding factor is that unchecked conversion is far better defined, better signalled in the sources (i.e. the use of potentially unsafe techniques is better flagged to the reader), and is far more likely to be portable than the use of address overlays. > I can't see why this is preferable over a straight address > clause of objects of a and b. Besides, when the needs comes, > often times one or the other object is already declared. > Therefore AV or BV, as appropriate, will have to be setup > to point to the already declared object. Seems like a lot > of extra stuff when one address clause is needed. The extra stuff, and most particularly the "with Unchecked_Conversion" in the context clause is welcome to raise red flags. This is NOT the kind of thing we want writers to do conveniently and inconspicuously. > Also, a lot of extra stuff when a single address clause > is called for. I don't see the advantage of these indirect > views. Also, is a_Access and/or b_Access are allocated > to user defined storage pools, then isn't this going to > create problems? You should use general access types, as indicated in my examples. > > I think I preferred the Ada 83 formulation. > > Do you mean "for b use at x'address;" ? No, I mean the rule in Ada 83 that said that use of address clauses to achieve overlays was always erroneous. The syntax is neither here nor there. Sent via Deja.com http://www.deja.com/ Before you buy. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-08 0:00 ` Robert Dewar @ 2000-05-09 0:00 ` Samuel T. Harris 2000-05-09 0:00 ` Ted Dennison 0 siblings, 1 reply; 21+ messages in thread From: Samuel T. Harris @ 2000-05-09 0:00 UTC (permalink / raw) Robert Dewar wrote: > > In article <3916D7F4.178B4FDE@Raytheon.com>, > "Samuel T. Harris" <samuel_t_harris@Raytheon.com> wrote: > > > The poster wasn't asking about UCing the pointers. > > The question was about UCing the data vs making an overlay. > > UCing pointers an another way to make overlays which are > > IMO less clear to the reader than a address clause. > > Well you can have any opinion you like. But unchecked conversion > is far better defined than overlay. The latter is completely > implementation defined, and may cause havoc due to descriptors > etc. As one who has done a lot of Ada 83, done some Ada 95 at home, and am waiting for my work environment to move to Ada 95, I am still being guided toward newer forms for the same old issues. Robert, the details in your clarrifying response now convince me the UC pointers is, in general, better than an overlay. I hope that method is applicable to the original poster! (I still think and address clause is more readable than your stuff, but better defined is to be preferred over simplicity.) > > > Conversion of access types only works when the access types > > are in the same storage pool. > > Good practice here is to use unchecked conversion only on > general access pointers which do NOT reference unconstrained > array types. > > > Just what is dubious about this advice. > > You are simpy defining two additional way to define an overlay > > yet you make no comment on the deciding factor! > > The deciding factor is that unchecked conversion is far better > defined, better signalled in the sources (i.e. the use of > potentially unsafe techniques is better flagged to the reader), > and is far more likely to be portable than the use of address > overlays. > > > I can't see why this is preferable over a straight address > > clause of objects of a and b. Besides, when the needs comes, > > often times one or the other object is already declared. > > Therefore AV or BV, as appropriate, will have to be setup > > to point to the already declared object. Seems like a lot > > of extra stuff when one address clause is needed. > > The extra stuff, and most particularly the "with > > Unchecked_Conversion" in the context clause is welcome > to raise red flags. This is NOT the kind of thing we want > writers to do conveniently and inconspicuously. You still haven't address my case where the source object is already defined. If it is not defined as aliased and I have no control over it, then would you advocate an UC on 'address into the pointer instead of an address overlay? > > > Also, a lot of extra stuff when a single address clause > > is called for. I don't see the advantage of these indirect > > views. Also, is a_Access and/or b_Access are allocated > > to user defined storage pools, then isn't this going to > > create problems? > > You should use general access types, as indicated in my > examples. > > > > I think I preferred the Ada 83 formulation. > > > > Do you mean "for b use at x'address;" ? > > No, I mean the rule in Ada 83 that said that use of address > clauses to achieve overlays was always erroneous. The syntax > is neither here nor there. Where angles fear to tread! In my experience, I've never had major incompatibility problems across compiler implementations. It is rare that such interfacing code deals with unconstrainted arrays or polymorphic variant records. Usually just run-of-the-mill scalars, static records, and constrainted arrays. > > Sent via Deja.com http://www.deja.com/ > Before you buy. -- Samuel T. Harris, Principal Engineer Raytheon, Aerospace Engineering Services "If you can make it, We can fake it!" ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-09 0:00 ` Samuel T. Harris @ 2000-05-09 0:00 ` Ted Dennison 2000-05-10 0:00 ` Marc A. Criley 0 siblings, 1 reply; 21+ messages in thread From: Ted Dennison @ 2000-05-09 0:00 UTC (permalink / raw) In article <39184D91.13BA15B4@Raytheon.com>, "Samuel T. Harris" <samuel_t_harris@Raytheon.com> wrote: > problems across compiler implementations. It is rare that > such interfacing code deals with unconstrainted arrays > or polymorphic variant records. Usually just run-of-the-mill > scalars, static records, and constrainted arrays. The typical use I've seen of it (UC-ing addresses into object pointers) is in converting random data objects into arays of bytes. Since the base type for one side is typically an unconstrained array of bytes, I think this is quite likely to be an issue. Usually this is done to convert some nice user data structure into something an entity outside of Ada (such as an OS call) can deal with. Just about any other use is going to be a hack around a badly-chosen type. Thus the Right Thing would be to redesign the type. -- T.E.D. http://www.telepath.com/~dennison/Ted/TED.html Sent via Deja.com http://www.deja.com/ Before you buy. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-09 0:00 ` Ted Dennison @ 2000-05-10 0:00 ` Marc A. Criley 2000-05-11 0:00 ` tmoran 0 siblings, 1 reply; 21+ messages in thread From: Marc A. Criley @ 2000-05-10 0:00 UTC (permalink / raw) Okay, if there's a simple answer to this I'm going to look really dumb for asking...but I'll take that chance :-) My goal has been to serialize an arbitrary object (the type of which is provided as a generic formal parameter) into a Stream_Element_Array for use with the AdaSockets package. I've been all over the RM95 looking for a nice, clean way to do this, and have not been able to find one. It appears then to come down to working with Unchecked_Conversion or the 'Address overlay approach (the latter of which was provided as the example in my original posting). If there's a straightforward way to accomplish what I'm _really_ trying to do, I would very much like to hear it! And performance does matter, since I want to minimize socket blocking. Oh, and to forestall the "Why not use the DSA?" question, the answer is that the required post-processing associated with GLADE just won't fly with clients, so I need to use the basic client/server model. Marc A. Criley Ted Dennison wrote: > > In article <39184D91.13BA15B4@Raytheon.com>, > "Samuel T. Harris" <samuel_t_harris@Raytheon.com> wrote: > > > problems across compiler implementations. It is rare that > > such interfacing code deals with unconstrainted arrays > > or polymorphic variant records. Usually just run-of-the-mill > > scalars, static records, and constrainted arrays. > > The typical use I've seen of it (UC-ing addresses into object pointers) > is in converting random data objects into arays of bytes. Since the base > type for one side is typically an unconstrained array of bytes, I think > this is quite likely to be an issue. > > Usually this is done to convert some nice user data structure into > something an entity outside of Ada (such as an OS call) can deal with. > Just about any other use is going to be a hack around a badly-chosen > type. Thus the Right Thing would be to redesign the type. > > -- > T.E.D. > > http://www.telepath.com/~dennison/Ted/TED.html > > Sent via Deja.com http://www.deja.com/ > Before you buy. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-10 0:00 ` Marc A. Criley @ 2000-05-11 0:00 ` tmoran 2000-05-12 0:00 ` tmoran 0 siblings, 1 reply; 21+ messages in thread From: tmoran @ 2000-05-11 0:00 UTC (permalink / raw) > My goal has been to serialize an arbitrary object (the type of which is > provided as a generic formal parameter) into a Stream_Element_Array for > use with the AdaSockets package. Declare a child, Sender_Type, say, of Ada.Streams.Root_Stream_Type, and overide the inherited (abstract) Read and Write routines. Write will be called with a Stream_Element_Array, which you will presumably send out through the socket. Then you can type Ptr_Sender_Type is access Sender_Type; Sender : Ptr_Sender_Type := new Sender_Type; generic type Some_Type is private; procedure Send_Some_Type(X:in Some_Type); procedure Send_Some_Type(X:in Some_Type) is begin Some_Type'Write(Sender, X); end Send_Some_Type; procedure Send_Integer is new Send_Some_Type(Integer); begin Send_Integer(27); -- make call(s) on Sender_Type Write routine If Some_Type is a record or array the system will automagically make calls on Sender_Type's Write routine with the individual components. If that is too slow, you can declare your own special writer routine and do "for My_Record_Type'Write use My_Special_Writer;" ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-11 0:00 ` tmoran @ 2000-05-12 0:00 ` tmoran 0 siblings, 0 replies; 21+ messages in thread From: tmoran @ 2000-05-12 0:00 UTC (permalink / raw) > My goal has been to serialize an arbitrary object (the type of which is > provided as a generic formal parameter) into a Stream_Element_Array for > use with the AdaSockets package. In Claw, we have: type Socket_Stream_Type(Socket : access Socket_Type'class) is new Ada.Streams.Root_Stream_Type with record ... procedure Write(Stream : in out Socket_Stream_Type; Item : in Ada.Streams.Stream_Element_Array); So you can declare an aliased object X of type Socket_Stream_Type. To open, close, etc, you make calls to Open(X.Socket), etc. Once the socket is open, "Data_Type'Write(X'access, Data);" will generate calls to Write(X.Socket, Data Components) as needed for the components of Data. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-01 0:00 Overlay allowability Marc A. Criley 2000-05-01 0:00 ` Ted Dennison @ 2000-05-01 0:00 ` Tucker Taft 2000-05-01 0:00 ` mark_biggar ` (2 more replies) 2000-05-01 0:00 ` tmoran 2000-05-02 0:00 ` Robert I. Eachus 3 siblings, 3 replies; 21+ messages in thread From: Tucker Taft @ 2000-05-01 0:00 UTC (permalink / raw) "Marc A. Criley" wrote: > > A few times in my career I've encountered situations where two different > representations of the same set of bits are desired in a high > performance application, and this has been effected with the aid of the > 'Address representation attribute. In Ada 95, an example of this would > be: > > N : Natural; > > SN : Stream_Element_Array(1..N'Size / System.Storage_Unit); > for SN'Address use N; I presume you meant: for SN'Address use N'Address. Also, N'Size/System.Storage_Unit is not what you want, probably. More likely is: (N'Size + System.Storage_Unit - 1)/System.Storage_Unit I.e., round the division up. N'Size is probably going to be 31 on your typical 32-bit computer. > > This has always struck me as somewhat iffy, but I confess I've used > it as well on a couple occasions with Ada 83. I've always found that > it works as one intuitively expects, so long as all alignment, layout > and sizing aspects are fully thought through and accommodated. > > So, is this within the definition of Ada 95? Or is it well-defined > only for certain constructs, say scalars and non-tagged types, and > dicey for others? Are there type constructs for which relying on it > is clearly a reliance on undefined behavior, is the whole construct a > reliance on undefined behavior? Is there a de facto, in place of a > formal, expectation that this should work as expected? This is well-defined in Ada 95, though as mentioned elsewhere, using unchecked conversion is more explicit and probably less likely to run into problems. As far as the Ada 95 RM, using 'Address for overlaying is safer than in Ada 83, because of RM95 13.3(19): If the Address of an object is specified ... then the implementation should not perform optimizations based on assumptions of no aliases. Note that this is implementation advice, not an implementation requirement. The probable reason it is advice rather than requirement is because of the difficulty of formulating this recommendation exactly and testably. > Marc A. Criley -- -Tucker Taft stt@averstar.com http://www.averstar.com/~stt/ Technical Director, Commercial Division, AverStar (formerly Intermetrics) (http://www.averstar.com/services/IT_consulting.html) Burlington, MA USA ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-01 0:00 ` Tucker Taft @ 2000-05-01 0:00 ` mark_biggar 2000-05-01 0:00 ` Keith Thompson 2000-05-03 0:00 ` Robert I. Eachus 2 siblings, 0 replies; 21+ messages in thread From: mark_biggar @ 2000-05-01 0:00 UTC (permalink / raw) In article <390DCBB2.CE2C1609@averstar.com>, Tucker Taft <stt@averstar.com> wrote: > "Marc A. Criley" wrote: > > > > A few times in my career I've encountered situations where two different > > representations of the same set of bits are desired in a high > > performance application, and this has been effected with the aid of the > > 'Address representation attribute. In Ada 95, an example of this would > > be: > > > > N : Natural; > > > > SN : Stream_Element_Array(1..N'Size / System.Storage_Unit); > > for SN'Address use N; > > I presume you meant: for SN'Address use N'Address. > > Also, N'Size/System.Storage_Unit is not what you want, probably. > More likely is: > (N'Size + System.Storage_Unit - 1)/System.Storage_Unit > > I.e., round the division up. > > N'Size is probably going to be 31 on your typical 32-bit computer. > > > > > This has always struck me as somewhat iffy, but I confess I've used > > it as well on a couple occasions with Ada 83. I've always found that > > it works as one intuitively expects, so long as all alignment, layout > > and sizing aspects are fully thought through and accommodated. > > > > So, is this within the definition of Ada 95? Or is it well-defined > > only for certain constructs, say scalars and non-tagged types, and > > dicey for others? Are there type constructs for which relying on it > > is clearly a reliance on undefined behavior, is the whole construct a > > reliance on undefined behavior? Is there a de facto, in place of a > > formal, expectation that this should work as expected? > > This is well-defined in Ada 95, though as mentioned elsewhere, using unchecked > conversion is more explicit and probably less likely to run into > problems. As far as the Ada 95 RM, using 'Address for overlaying is > safer than in Ada 83, because of RM95 13.3(19): > > If the Address of an object is specified ... then the implementation > should not perform optimizations based on assumptions of no aliases. > > Note that this is implementation advice, not an implementation requirement. > The probable reason it is advice rather than requirement is because of > the difficulty of formulating this recommendation exactly and testably. Another thing to watch out for is Initializations. if both variables are of a type that has either explisit or implisit imitialization then both initializations will be performed. The following example is from a froends code that took both of us hours to figure out what was happening: type A_foo is access Foo; type A_bar is access Bar; F: A_foo := new Foo(...); B: A_Bar; for B'ADDRESS use F'ADDRESS; The intent is to view the same chunk of memory in differnet ways. (This is obviously a case where Unchecked_Conversion makes MUCH more sense but unformunately the code was a re-implementation of a C program that used pointer casting for just this and the writer [a third party] was an ex-C programmer.) The problem is that the implisit initialazation of B to Null was clobbering the pointer to the memory chunk. This fix for this (other than to rewrite using Unchecked_Conversion) was to add a pragma EXPORT(B, Ada); to suppress the initialization. -- Mark Biggar mark@biggar.org Sent via Deja.com http://www.deja.com/ Before you buy. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-01 0:00 ` Tucker Taft 2000-05-01 0:00 ` mark_biggar @ 2000-05-01 0:00 ` Keith Thompson 2000-05-08 0:00 ` Tucker Taft 2000-05-03 0:00 ` Robert I. Eachus 2 siblings, 1 reply; 21+ messages in thread From: Keith Thompson @ 2000-05-01 0:00 UTC (permalink / raw) Tucker Taft <stt@averstar.com> writes: > "Marc A. Criley" wrote: [...] > > N : Natural; > > > > SN : Stream_Element_Array(1..N'Size / System.Storage_Unit); > > for SN'Address use N; > > I presume you meant: for SN'Address use N'Address. > > Also, N'Size/System.Storage_Unit is not what you want, probably. > More likely is: > (N'Size + System.Storage_Unit - 1)/System.Storage_Unit > > I.e., round the division up. > > N'Size is probably going to be 31 on your typical 32-bit computer. Actually, I think N'Size is more likely to be 32, though Natural'Size is likely to be 31. A standalone object (like N in the example) is almost certain to occupy a whole number of storage units, and to be aligned on a storage-unit boundary. -- Keith Thompson (The_Other_Keith) kst@cts.com <http://www.ghoti.net/~kst> San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst> Welcome to the last year of the 20th century. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-01 0:00 ` Keith Thompson @ 2000-05-08 0:00 ` Tucker Taft 0 siblings, 0 replies; 21+ messages in thread From: Tucker Taft @ 2000-05-08 0:00 UTC (permalink / raw) Keith Thompson wrote: > > Tucker Taft <stt@averstar.com> writes: > > "Marc A. Criley" wrote: > [...] > > > N : Natural; > ... > > N'Size is probably going to be 31 on your typical 32-bit computer. > > Actually, I think N'Size is more likely to be 32, though Natural'Size > is likely to be 31. A standalone object (like N in the example) is > almost certain to occupy a whole number of storage units, and to be > aligned on a storage-unit boundary. Right, I was confused. Only a subtype or a component would typically end up with a size like 31. A stand-alone object would almost certainly end up with an integral number of storage elements (except perhaps on a bit-addressible machine like the old and bizarre Burroughs B-17 [I think that was its number]). Of course rounding up doesn't hurt... (trying to salvage some amount of dignity here ;-). > > -- > Keith Thompson (The_Other_Keith) kst@cts.com <http://www.ghoti.net/~kst> > San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst> > Welcome to the last year of the 20th century. -- -Tucker Taft stt@averstar.com http://www.averstar.com/~stt/ Technical Director, Commercial Division, AverStar (formerly Intermetrics) (http://www.averstar.com/services/IT_consulting.html) Burlington, MA USA ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-01 0:00 ` Tucker Taft 2000-05-01 0:00 ` mark_biggar 2000-05-01 0:00 ` Keith Thompson @ 2000-05-03 0:00 ` Robert I. Eachus 2 siblings, 0 replies; 21+ messages in thread From: Robert I. Eachus @ 2000-05-03 0:00 UTC (permalink / raw) Tucker Taft wrote: > N'Size is probably going to be 31 on your typical 32-bit computer. I know that Natural'Size is probably 31, but I thought that N'Size would normally be 32. "...The Size of an object is at least as large as that of its subtype, unless..." RM 13.3(48) So I always assumed that the Natural'Size glitch only applied to the subtype. I guess a compiler could return 32 for N'Size, does anyone know of a compiler that does so? (Or in general returns wordsize-1 as the size for standalone objects of subtype Natural.) ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-01 0:00 Overlay allowability Marc A. Criley 2000-05-01 0:00 ` Ted Dennison 2000-05-01 0:00 ` Tucker Taft @ 2000-05-01 0:00 ` tmoran 2000-05-02 0:00 ` Robert I. Eachus 3 siblings, 0 replies; 21+ messages in thread From: tmoran @ 2000-05-01 0:00 UTC (permalink / raw) >A few times in my career I've encountered situations where two different >representations of the same set of bits are desired in a high Why can't you use Unchecked_Conversion? Then at least the compiler has an opportunity to warn you if dope vectors, tags, alignment padding, etc, are going to result in a different number of bits than you expected. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-01 0:00 Overlay allowability Marc A. Criley ` (2 preceding siblings ...) 2000-05-01 0:00 ` tmoran @ 2000-05-02 0:00 ` Robert I. Eachus 2000-05-03 0:00 ` Marc A. Criley 3 siblings, 1 reply; 21+ messages in thread From: Robert I. Eachus @ 2000-05-02 0:00 UTC (permalink / raw) "Marc A. Criley" wrote: This one should be in the FAQ... > A few times in my career I've encountered situations where two different > representations of the same set of bits are desired in a high > performance application, and this has been effected with the aid of the > 'Address representation attribute. In Ada 95, an example of this would > be: > > N : Natural; > > SN : Stream_Element_Array(1..N'Size / System.Storage_Unit); > for SN'Address use N; > > This has always struck me as somewhat iffy, but I confess I've used > it as well on a couple occasions with Ada 83. I've always found that > it works as one intuitively expects, so long as all alignment, layout > and sizing aspects are fully thought through and accommodated. > > So, is this within the definition of Ada 95? Or is it well-defined > only for certain constructs, say scalars and non-tagged types, and > dicey for others? Are there type constructs for which relying on it > is clearly a reliance on undefined behavior, is the whole construct a > reliance on undefined behavior? Is there a de facto, in place of a > formal, expectation that this should work as expected? Hmmm. The RM is very clear about this: "If an Address is specified, it is the programmer's responsibility to ensure that the address is valid; otherwise, program execution is erroneous." RM 13.3(13). So first off, your example has a bug in it, and will almost certainly result in erroneous execution. I'm sure you intended to write: for SN'Address use N'Address; correct? Your code fragment as written would be erroneous or not depending on whether or not the value in N corresponded to a legitimate address when the representation clause was elaborated. Now let's go to the much more interesting case of what you intended to write. First, N'Address is likely to be a valid address, so the program execution will not be erroneous (or at least, not due to the elaboration of this construct). Note, that just being the result of an 'Address clause is not sufficient to make an address valid, you could, for example, say "use Main_Program'Address;" "use Bit_Array(7)'Address;" or even "Some_Constant'Address;" but the clause above should be safe, unless an unfriendly compiler sticks N in a register. Most Ada compilers are very friendly in this case, but why not warn maintainers by making N explicitly aliased. You mentioned, alignment, layout, and sizing aspects, and (surprise!) these are discussed in great detail in RM 13.3. There are some things you can count on, some you can--and often should--specify, and some which will be implementation defined. But there are some other details that you should be aware of. You usually don't want any default initializations that are associated with the subtype of SN to be performed. The fact that you don't provide a default value, doesn't prevent the compiler from initializing something behind your back. (Everyone knows that access values are initialized to null in the absence of other initializations, but compilers may choose to initialize records with gaps to make comparisions easier, and you certainly don't want your code to fail if someone compiles it with pragma Normalize_Scalars, or adds a default initialization to some subtype.) Also, if you are using both representations of the data in the same code, you need to think seriously about which declarations will require pragma Volatile, Atomic, Volatile_Components or Atomic_Components. Note that these are in Annex C, and that the use of one of these pragmas may result in the program being rejected. A "nice" compiler will note the aliasing, and not put N in a register. But the real issues you have to worry about are much more subtle. Assuming that you used the right pragma for your code, and that the compiler doesn't have a serious bug, the compiler will--instead of producing what you will consider to be buggy code--tell you that, on this hardware, your code cannot be correctly implemented. In your example, assuming that the Stream_Element_Array comes from Ada.Streams, it is likely that you can safely apply pragma Atomic to N and pragma Volatile_Components to SN. All this may not be necessary, and in fact Ada compilers do try to be friendly, but you should require the behavior that you actually require, if only for documentation. So the general template for the idiom is: N : aliased Natural; pragma Atomic(N); SN : Stream_Element_Array(1..N'Size / System.Storage_Unit); for SN'Address use N'Address; pragma Volatile_Components(SN); pragma Import(SN); I made N atomic, since you probably do want to insist that you don't see "half" of an update. If N was for example a double word scalar, the pragma might be necessary. (And compilers can often do double loads and stores on hardware which only supports single word integers--think long float.) I used Volatile_Components on SN because it is much more likely to be accepted, and you would probably only need to use Atomic_Components if you had multiple tasks involved. This is the type of thinking which the programmer/software engineer needs to do as part of the design. Not putting the pragmas in--or a comment as to why they are not there--requires that every reader or maintainer do that analysis all over again. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Overlay allowability 2000-05-02 0:00 ` Robert I. Eachus @ 2000-05-03 0:00 ` Marc A. Criley 0 siblings, 0 replies; 21+ messages in thread From: Marc A. Criley @ 2000-05-03 0:00 UTC (permalink / raw) Bob, Thanks for doing the analysis of this little example, I agree that the FAQ would be well-served by including your writeup within it (with, of course, the inadvertent omission of the 'Address on "for SN'Address use N;" corrected :-) In the real code where this would be used, "N" is actually the parameter that is received into the procedure that does the overlaying, and is an instance of a generic formal type, of which nothing concerning its content and constituents are known. (BTW, no references to this variable other than remapping it into a Stream_Element_Array occur.) This of course bolsters your analysis that the developer then needs to specify exactly what is expected of such instances in a context, rather than requiring developers to re-perform the analysis to understand the conditions under which this executes. Thanks again, Marc "Robert I. Eachus" wrote: > > This one should be in the FAQ... > > "Marc A. Criley" wrote: > > > A few times in my career I've encountered situations where two different > > representations of the same set of bits are desired in a high > > performance application, and this has been effected with the aid of the > > 'Address representation attribute. In Ada 95, an example of this would > > be: > > > > N : Natural; > > > > SN : Stream_Element_Array(1..N'Size / System.Storage_Unit); > > for SN'Address use N; > > > > This has always struck me as somewhat iffy, but I confess I've used > > it as well on a couple occasions with Ada 83. I've always found that > > it works as one intuitively expects, so long as all alignment, layout > > and sizing aspects are fully thought through and accommodated. > > > > So, is this within the definition of Ada 95? Or is it well-defined > > only for certain constructs, say scalars and non-tagged types, and > > dicey for others? Are there type constructs for which relying on it > > is clearly a reliance on undefined behavior, is the whole construct a > > reliance on undefined behavior? Is there a de facto, in place of a > > formal, expectation that this should work as expected? > > Hmmm. The RM is very clear about this: > > "If an Address is specified, it is the programmer's responsibility > to ensure that the address is valid; otherwise, program execution is > erroneous." RM 13.3(13). > > So first off, your example has a bug in it, and will almost > certainly result in erroneous execution. I'm sure you intended to > write: > > for SN'Address use N'Address; > > correct? Your code fragment as written would be erroneous or not > depending on whether or not the value in N corresponded to a legitimate > address when the representation clause was elaborated. > > Now let's go to the much more interesting case of what you > intended to write. First, N'Address is likely to be a valid address, so > the program execution will not be erroneous (or at least, not due to the > elaboration of this construct). Note, that just being the result of an > 'Address clause is not sufficient to make an address valid, you could, > for example, say "use Main_Program'Address;" "use Bit_Array(7)'Address;" > or even "Some_Constant'Address;" but the clause above should be safe, > unless an unfriendly compiler sticks N in a register. Most Ada > compilers are very friendly in this case, but why not warn maintainers > by making N explicitly aliased. > > You mentioned, alignment, layout, and sizing aspects, and > (surprise!) these are discussed in great detail in RM 13.3. There are > some things you can count on, some you can--and often should--specify, > and some which will be implementation defined. But there are some other > details that you should be aware of. You usually don't want any default > initializations that are associated with the subtype of SN to be > performed. The fact that you don't provide a default value, doesn't > prevent the compiler from initializing something behind your back. > (Everyone knows that access values are initialized to null in the > absence of other initializations, but compilers may choose to initialize > records with gaps to make comparisions easier, and you certainly don't > want your code to fail if someone compiles it with pragma > Normalize_Scalars, or adds a default initialization to some subtype.) > > Also, if you are using both representations of the data in the same > code, you need to think seriously about which declarations will require > pragma Volatile, Atomic, Volatile_Components or Atomic_Components. Note > that these are in Annex C, and that the use of one of these pragmas may > result in the program being rejected. A "nice" compiler will note the > aliasing, and not put N in a register. But the real issues you have to > worry about are much more subtle. Assuming that you used the right > pragma for your code, and that the compiler doesn't have a serious bug, > the compiler will--instead of producing what you will consider to be > buggy code--tell you that, on this hardware, your code cannot be > correctly implemented. In your example, assuming that the > Stream_Element_Array comes from Ada.Streams, it is likely that you can > safely apply pragma Atomic to N and pragma Volatile_Components to SN. > All this may not be necessary, and in fact Ada compilers do try to be > friendly, but you should require the behavior that you actually require, > if only for documentation. So the general template for the idiom is: > > N : aliased Natural; > pragma Atomic(N); > > SN : Stream_Element_Array(1..N'Size / System.Storage_Unit); > for SN'Address use N'Address; > pragma Volatile_Components(SN); > pragma Import(SN); > > I made N atomic, since you probably do want to insist that you don't > see "half" of an update. If N was for example a double word scalar, the > pragma might be necessary. (And compilers can often do double loads and > stores on hardware which only supports single word integers--think long > float.) I used Volatile_Components on SN because it is much more likely > to be accepted, and you would probably only need to use > Atomic_Components if you had multiple tasks involved. This is the type > of thinking which the programmer/software engineer needs to do as part > of the design. Not putting the pragmas in--or a comment as to why they > are not there--requires that every reader or maintainer do that analysis > all over again. ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2000-05-12 0:00 UTC | newest] Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2000-05-01 0:00 Overlay allowability Marc A. Criley 2000-05-01 0:00 ` Ted Dennison 2000-05-03 0:00 ` Samuel T. Harris 2000-05-03 0:00 ` Robert A Duff 2000-05-03 0:00 ` Ted Dennison 2000-05-04 0:00 ` Robert Dewar 2000-05-08 0:00 ` Samuel T. Harris 2000-05-08 0:00 ` Robert Dewar 2000-05-09 0:00 ` Samuel T. Harris 2000-05-09 0:00 ` Ted Dennison 2000-05-10 0:00 ` Marc A. Criley 2000-05-11 0:00 ` tmoran 2000-05-12 0:00 ` tmoran 2000-05-01 0:00 ` Tucker Taft 2000-05-01 0:00 ` mark_biggar 2000-05-01 0:00 ` Keith Thompson 2000-05-08 0:00 ` Tucker Taft 2000-05-03 0:00 ` Robert I. Eachus 2000-05-01 0:00 ` tmoran 2000-05-02 0:00 ` Robert I. Eachus 2000-05-03 0:00 ` Marc A. Criley
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox