* Type of the target of an assignment shall not be abstract @ 2010-02-14 14:20 Gautier write-only 2010-02-14 17:57 ` Dmitry A. Kazakov ` (2 more replies) 0 siblings, 3 replies; 10+ messages in thread From: Gautier write-only @ 2010-02-14 14:20 UTC (permalink / raw) Hello, A question for the RM hermeneutists. The instruction marked below with ">>>" goes well through one Ada 95 compiler (GNAT with -gnat95) but is not accepted by another one (ObjectAda 7.2.2). Which compiler is right ? procedure Init( xl : in out Excel_Out_Stream'Class; format : Excel_type:= Default_Excel_type ) is dummy_xl_with_defaults: Excel_Out_File; begin -- Check if we are trying to re-use a half-finished object (ouch!): if xl.is_created and not xl.is_closed then raise Excel_Stream_Not_Closed; end if; dummy_xl_with_defaults.format:= format; >>> Excel_Out_Stream(xl):= Excel_Out_Stream(dummy_xl_with_defaults); end Init; >>> excel_out.adb: Error: line 595 col 5 LRM:3.9.3(8), The type of the target of an assignment shall not be abstract For those asking themselves what the *@#$! that code is doing, since the xl variable is already initialized, the purpose of the := is to re- initialize an object (xl) with the default values of the root type. Since the root type is abstract, I need a concrete derived object (dummy_xl_with_defaults) to get these default values. Subsidiary question: is there another way of doing that in one ':=' ? The whole package is visible @ http://excel-writer.sourceforge.net/ew_html/excel_out__adb.htm#553_13 ______________________________________________________________ Gautier's Ada programming -- http://gautiersblog.blogspot.com/ ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Type of the target of an assignment shall not be abstract 2010-02-14 14:20 Type of the target of an assignment shall not be abstract Gautier write-only @ 2010-02-14 17:57 ` Dmitry A. Kazakov 2010-02-15 17:05 ` Adam Beneschan 2010-02-28 17:00 ` Gautier write-only 2 siblings, 0 replies; 10+ messages in thread From: Dmitry A. Kazakov @ 2010-02-14 17:57 UTC (permalink / raw) On Sun, 14 Feb 2010 06:20:32 -0800 (PST), Gautier write-only wrote: > A question for the RM hermeneutists. > The instruction marked below with ">>>" goes well through one Ada 95 > compiler (GNAT with -gnat95) but is not accepted by another one > (ObjectAda 7.2.2). > Which compiler is right ? > > procedure Init( > xl : in out Excel_Out_Stream'Class; > format : Excel_type:= Default_Excel_type > ) > is > dummy_xl_with_defaults: Excel_Out_File; > begin > -- Check if we are trying to re-use a half-finished object > (ouch!): > if xl.is_created and not xl.is_closed then > raise Excel_Stream_Not_Closed; > end if; > dummy_xl_with_defaults.format:= format; >>>> Excel_Out_Stream(xl):= Excel_Out_Stream(dummy_xl_with_defaults); > end Init; > >>>> excel_out.adb: Error: line 595 col 5 LRM:3.9.3(8), The type of the target of an assignment shall not be abstract > > For those asking themselves what the *@#$! that code is doing, since > the xl variable is already initialized, the purpose of the := is to re- > initialize an object (xl) with the default values of the root type. > Since the root type is abstract, I need a concrete derived object > (dummy_xl_with_defaults) to get these default values. Subsidiary > question: is there another way of doing that in one ':=' ? package P is type T is abstract tagged private; procedure Reset (X : in out T'Class); private type Root is tagged record -- Non-abstract I : Integer; end record; type T is abstract new Root with null record; end P; package body P is Defaults : Root := (I => 123); procedure Reset (X : in out T'Class) is begin Root (X) := Defaults; end Reset; end P;. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Type of the target of an assignment shall not be abstract 2010-02-14 14:20 Type of the target of an assignment shall not be abstract Gautier write-only 2010-02-14 17:57 ` Dmitry A. Kazakov @ 2010-02-15 17:05 ` Adam Beneschan 2010-02-15 19:00 ` Hibou57 (Yannick Duchêne) 2010-02-16 0:59 ` Adam Beneschan 2010-02-28 17:00 ` Gautier write-only 2 siblings, 2 replies; 10+ messages in thread From: Adam Beneschan @ 2010-02-15 17:05 UTC (permalink / raw) On Feb 14, 6:20 am, Gautier write-only <gautier_niou...@hotmail.com> wrote: > Hello, > > A question for the RM hermeneutists. > The instruction marked below with ">>>" goes well through one Ada 95 > compiler (GNAT with -gnat95) but is not accepted by another one > (ObjectAda 7.2.2). > Which compiler is right ? > > procedure Init( > xl : in out Excel_Out_Stream'Class; > format : Excel_type:= Default_Excel_type > ) > is > dummy_xl_with_defaults: Excel_Out_File; > begin > -- Check if we are trying to re-use a half-finished object > (ouch!): > if xl.is_created and not xl.is_closed then > raise Excel_Stream_Not_Closed; > end if; > dummy_xl_with_defaults.format:= format;>>> Excel_Out_Stream(xl):= Excel_Out_Stream(dummy_xl_with_defaults); > > end Init; > > >>> excel_out.adb: Error: line 595 col 5 LRM:3.9.3(8), The type of the target of an assignment shall not be abstract This is indeed illegal, although offhand I'm not sure it should be. -- Adam ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Type of the target of an assignment shall not be abstract 2010-02-15 17:05 ` Adam Beneschan @ 2010-02-15 19:00 ` Hibou57 (Yannick Duchêne) 2010-02-23 21:19 ` Robert A Duff 2010-02-16 0:59 ` Adam Beneschan 1 sibling, 1 reply; 10+ messages in thread From: Hibou57 (Yannick Duchêne) @ 2010-02-15 19:00 UTC (permalink / raw) Le Mon, 15 Feb 2010 18:05:09 +0100, Adam Beneschan <adam@irvine.com> a écrit: > > This is indeed illegal, although offhand I'm not sure it should be. You cannot create an instance of an abstract type, initialized or not, so assignment is unlikely to be legal. Whatever it is of instantiation or assignment, this would not make no sense with an abstract type, as some method would not be defined. Well, to be honest, one alternative could have been to allow such a thing and simply disallow invocation of abstract methods (Borland Turbo Pascal did this), but then, what about if the object is passed as a class-wide parameter ? The method receiving the it as a class-wide parameter may access an abstract method. Allowing instantiation of abstracts and disallowing to pass it where class-wide is expected, would not have been clean. -- No-no, this isn't an oops ...or I hope (TM) - Don't blame me... I'm just not lucky ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Type of the target of an assignment shall not be abstract 2010-02-15 19:00 ` Hibou57 (Yannick Duchêne) @ 2010-02-23 21:19 ` Robert A Duff 0 siblings, 0 replies; 10+ messages in thread From: Robert A Duff @ 2010-02-23 21:19 UTC (permalink / raw) "Hibou57 (Yannick Duch�ne)" <yannick_duchene@yahoo.fr> writes: > Le Mon, 15 Feb 2010 18:05:09 +0100, Adam Beneschan <adam@irvine.com> a > �crit: >> >> This is indeed illegal, although offhand I'm not sure it should be. > You cannot create an instance of an abstract type, initialized or not, > so assignment is unlikely to be legal. Whatever it is of instantiation > or assignment, this would not make no sense with an abstract type, as > some method would not be defined. Well, to be honest, one alternative > could have been to allow such a thing and simply disallow invocation of > abstract methods (Borland Turbo Pascal did this), but then, what about > if the object is passed as a class-wide parameter ? The method > receiving the it as a class-wide parameter may access an abstract > method. Allowing instantiation of abstracts and disallowing to pass it > where class-wide is expected, would not have been clean. I think it would make sense to allow creation of objects of an abstract type, if you forbid conversion to class-wide (including the case you mention, where there's an implicit conversion to class-wide when passing a specific actual to a class-wide formal). I guess assignments need to be forbidden, too, as somebody mentioned in this thread -- in case there's an abstract Adjust. The one case where I've wanted this feature is when I want to use a function call as the ancestor part of an extension aggregate, where the ancestor is abstract. I don't like being forced to use default values in this case. Alternatively, you could use a run-time check (any call to an abstract subprogram raises an exception). Probably a bad idea! - Bob ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Type of the target of an assignment shall not be abstract 2010-02-15 17:05 ` Adam Beneschan 2010-02-15 19:00 ` Hibou57 (Yannick Duchêne) @ 2010-02-16 0:59 ` Adam Beneschan 2010-02-16 10:03 ` Gautier write-only 1 sibling, 1 reply; 10+ messages in thread From: Adam Beneschan @ 2010-02-16 0:59 UTC (permalink / raw) On Feb 15, 9:05 am, Adam Beneschan <a...@irvine.com> wrote: > > A question for the RM hermeneutists. > > The instruction marked below with ">>>" goes well through one Ada 95 > > compiler (GNAT with -gnat95) but is not accepted by another one > > (ObjectAda 7.2.2). > > Which compiler is right ? > > > procedure Init( > > xl : in out Excel_Out_Stream'Class; > > format : Excel_type:= Default_Excel_type > > ) > > is > > dummy_xl_with_defaults: Excel_Out_File; > > begin > > -- Check if we are trying to re-use a half-finished object > > (ouch!): > > if xl.is_created and not xl.is_closed then > > raise Excel_Stream_Not_Closed; > > end if; > > dummy_xl_with_defaults.format:= format;>>> Excel_Out_Stream(xl):= Excel_Out_Stream(dummy_xl_with_defaults); > > > end Init; > > > >>> excel_out.adb: Error: line 595 col 5 LRM:3.9.3(8), The type of the target of an assignment shall not be abstract > > This is indeed illegal, although offhand I'm not sure it should be. FYI, I asked about this on Ada-Comment, and got a response from Randy. Making this legal would be a problem, since there's a possibility that the abstract type has an abstract Adjust routine. If the assignment on the abstract view were allowed (even though it's an abstract "view conversion" of an object with a concrete type), it would be possible that a nonexistent Adjust routine would be called, and that sort of thing is prohibited by the language. On the other hand, it's probably a problem even if the type isn't abstract. If you use a view conversion on the left side of an assignment T2(X) := <something>; and T2 is a controlled type, and X's type is a type derived from T2, then an Adjust will be called on just the "T2" portion of X but this Adjust won't affect any other component of the type extension. IMHO, there's a good chance that this will not produce the desired result. The same is true if T2(X) is passed as an OUT or IN OUT parameter to some procedure, and the procedure assigns to the parameter as a whole. Unfortunately, it's probably too late to fix Ada to prevent things like this, or to allow things like this in an abstract case. My own recommendation: If you want the 14 components of the abstract type Excel_Out_Stream to be treated as a unit, then make them a unit--- i.e. define a record type with 14 components, and then Excel_Out_Stream would have just one component of that record type. Of course, that decision probably has to be made when the package is first written; making that change now would require changing how all those components are accessed everywhere else in the program. Barring that, you can either write 14 assignment statements and hope the compiler is smart enough to optimize them, or you can use a "trick" like Dmitry's suggestion, which will "work" but (in my opinion) doesn't help set up a type structure that accurately reflects the concepts in your program. -- Adam ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Type of the target of an assignment shall not be abstract 2010-02-16 0:59 ` Adam Beneschan @ 2010-02-16 10:03 ` Gautier write-only 2010-02-16 12:14 ` Gautier write-only 2010-02-16 16:12 ` Adam Beneschan 0 siblings, 2 replies; 10+ messages in thread From: Gautier write-only @ 2010-02-16 10:03 UTC (permalink / raw) On 16 Feb., 01:59, Adam Beneschan <a...@irvine.com>: > FYI, I asked about this on Ada-Comment, and got a response from > Randy. [...] Thanks! IHMO, no need to worry about how well or not the standard handles that. To answer my original question, can I conclude that GNAT is wrong on that case, and that I can send a report ? > My own recommendation: If you want the 14 components of the abstract > type Excel_Out_Stream to be treated as a unit, then make them a unit--- > i.e. define a record type with 14 components, and then > Excel_Out_Stream would have just one component of that record type. > Of course, that decision probably has to be made when the package is > first written; making that change now would require changing how all > those components are accessed everywhere else in the program. Barring > that, you can either write 14 assignment statements and hope the > compiler is smart enough to optimize them, or you can use a "trick" > like Dmitry's suggestion, which will "work" but (in my opinion) > doesn't help set up a type structure that accurately reflects the > concepts in your program. Sure, but isn't your recommendation a trick as well ? Then I should write xl.X.blabla all over the package's body (where X is the record type you suggest). That for sure will pervert the concepts, readability, etc. Choosing between both tricks, I'd prefer Dmitry's. I'll give a clear name to the concrete-before-abstract type, like "Pre_Root", and try to have it private. Let's see how it turns out... Thanks Gautier ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Type of the target of an assignment shall not be abstract 2010-02-16 10:03 ` Gautier write-only @ 2010-02-16 12:14 ` Gautier write-only 2010-02-16 16:12 ` Adam Beneschan 1 sibling, 0 replies; 10+ messages in thread From: Gautier write-only @ 2010-02-16 12:14 UTC (permalink / raw) > Choosing between both tricks, I'd prefer Dmitry's. > I'll give a clear name to the concrete-before-abstract type, like > "Pre_Root", and try to have it private. > Let's see how it turns out... It turns out perfectly. *** Spec, private part: -- We have a concrete type as hidden ancestor of the Excel_Out_Stream root -- type. A variable of that type is initialized with default values and -- can help re-initialize a Excel_Out_Stream when re-used several times. -- See the Reset procedure in body. -- type Excel_Out_Pre_Root_Type is tagged record [the 14 components] end record; type Excel_Out_Stream is abstract new Excel_Out_Pre_Root_Type with null record; *** Body: procedure Reset( xl : in out Excel_Out_Stream'Class; format : Excel_type:= Default_Excel_type ) is dummy_xl_with_defaults: Excel_Out_Pre_Root_Type; begin ... dummy_xl_with_defaults.format:= format; Excel_Out_Pre_Root_Type(xl):= dummy_xl_with_defaults; end Reset; *** GNAT and ObjectAda are happy, I as well :-) Philosophically, it seems reasonable that an abstract type should be somewhat "limited" in its use (NB: I've put ""'s around the word 'limited' :-) ) ______________________________________________________________ Gautier's Ada programming -- http://gautiersblog.blogspot.com/ ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Type of the target of an assignment shall not be abstract 2010-02-16 10:03 ` Gautier write-only 2010-02-16 12:14 ` Gautier write-only @ 2010-02-16 16:12 ` Adam Beneschan 1 sibling, 0 replies; 10+ messages in thread From: Adam Beneschan @ 2010-02-16 16:12 UTC (permalink / raw) On Feb 16, 2:03 am, Gautier write-only <gautier_niou...@hotmail.com> wrote: > On 16 Feb., 01:59, Adam Beneschan <a...@irvine.com>: > > > FYI, I asked about this on Ada-Comment, and got a response from > > Randy. [...] > > Thanks! > IHMO, no need to worry about how well or not the standard handles > that. > To answer my original question, can I conclude that GNAT is wrong on > that case, and that I can send a report ? Yes, if GNAT is accepting this, then it's wrong. -- Adam ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Type of the target of an assignment shall not be abstract 2010-02-14 14:20 Type of the target of an assignment shall not be abstract Gautier write-only 2010-02-14 17:57 ` Dmitry A. Kazakov 2010-02-15 17:05 ` Adam Beneschan @ 2010-02-28 17:00 ` Gautier write-only 2 siblings, 0 replies; 10+ messages in thread From: Gautier write-only @ 2010-02-28 17:00 UTC (permalink / raw) Just in case, here is a reduced example: -- package Abstrax is type Root is abstract tagged private; type T1 is new Root with private; procedure Reset(x: in out Root'Class); private type Root is abstract tagged record i: Integer:= 11; end record; type T1 is new Root with record j: Integer:= 22; end record; end; -- package body Abstrax is procedure Reset (x: in out Root'Class) is y: T1; begin Root(x):= Root(y); -- ^---- Wrong here ! end Reset; end Abstrax; -- Gautier ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2010-02-28 17:00 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-02-14 14:20 Type of the target of an assignment shall not be abstract Gautier write-only 2010-02-14 17:57 ` Dmitry A. Kazakov 2010-02-15 17:05 ` Adam Beneschan 2010-02-15 19:00 ` Hibou57 (Yannick Duchêne) 2010-02-23 21:19 ` Robert A Duff 2010-02-16 0:59 ` Adam Beneschan 2010-02-16 10:03 ` Gautier write-only 2010-02-16 12:14 ` Gautier write-only 2010-02-16 16:12 ` Adam Beneschan 2010-02-28 17:00 ` Gautier write-only
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox