* Limited returns @ 2008-06-23 14:21 Dmitry A. Kazakov 2008-06-23 15:04 ` fedya_fedyakoff ` (2 more replies) 0 siblings, 3 replies; 17+ messages in thread From: Dmitry A. Kazakov @ 2008-06-23 14:21 UTC (permalink / raw) Let's consider this: with Ada.Finalization; procedure Test_Limited_Stuff is type I is limited interface; type T is new Ada.Finalization.Limited_Controlled with record A : Integer; end record; type S is new T and I with record Self : not null access S'Class := S'Unchecked_Access; end record; function Factory return I'Class is begin return X : S; -- GNAT: wrong type for return_subtype_indication end Factory; begin null; end Test_Limited_Stuff; Is it illegal? I am surprised why? S is in I'Class. OK, if that is indeed illegal, then let's make another try: function Factory return I'Class is begin return X : I'Class := S'(T with others => <>); -- GNAT: expected an access type with designated type "S'Class" defined ... -- found an access type with designated type "I'Class" defined ... end Factory; ...still illegal, but more interesting. It seems that a Rosen's trick member cannot be initialized because the object's type is more general than the designated access type. It should not be so. A compiler bug? -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-23 14:21 Limited returns Dmitry A. Kazakov @ 2008-06-23 15:04 ` fedya_fedyakoff 2008-06-23 15:20 ` fedya_fedyakoff 2008-06-23 15:49 ` Adam Beneschan 2008-06-23 15:15 ` Adam Beneschan 2008-06-26 12:35 ` Egil Høvik 2 siblings, 2 replies; 17+ messages in thread From: fedya_fedyakoff @ 2008-06-23 15:04 UTC (permalink / raw) Hehe, and let's consider this: with Ada.Finalization; procedure Test_Limited_Stuff is type E is ( Make_S, Make_S1 ); type I is interface; type T is new Ada.Finalization.Controlled with record A : Integer; end record; type S is new T and I with record --Self : not null access S'Class := S'Unchecked_Access; B: Integer; end record; type S1 is new T and I with record --Self : not null access S1'Class := S1'Unchecked_Access; N: String(1..256); end record; function Factory( w: E ) return I'Class is begin if w = Make_S then return S'(Ada.Finalization.Controlled with A => 0, B => 1); else return S1'(Ada.Finalization.Controlled with A => 0, N => (others => 10) ); end if; end Factory; Value : I'Class := Factory(Make_S); begin Value := Factory(Make_S1); end Test_Limited_Stuff; Crashed pretty badly with CONSTRAINT_ERROR, whining about tag check error. Seems its completely buggy and unusable. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-23 15:04 ` fedya_fedyakoff @ 2008-06-23 15:20 ` fedya_fedyakoff 2008-06-23 16:53 ` Dmitry A. Kazakov 2008-06-23 15:49 ` Adam Beneschan 1 sibling, 1 reply; 17+ messages in thread From: fedya_fedyakoff @ 2008-06-23 15:20 UTC (permalink / raw) > Crashed pretty badly with CONSTRAINT_ERROR, whining about tag check > error. though i can't fugure out how it could check that in compile time... can it? >Seems its completely buggy and unusable. seems my bad. taking that back. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-23 15:20 ` fedya_fedyakoff @ 2008-06-23 16:53 ` Dmitry A. Kazakov 2008-06-24 10:56 ` fedya_fedyakoff 0 siblings, 1 reply; 17+ messages in thread From: Dmitry A. Kazakov @ 2008-06-23 16:53 UTC (permalink / raw) On Mon, 23 Jun 2008 08:20:51 -0700 (PDT), fedya_fedyakoff@inbox.ru wrote: >> Crashed pretty badly with CONSTRAINT_ERROR, whining about tag check >> error. > > though i can't fugure out how it could check that in compile time... > can it? Even if it could, that would not make the program illegal. The compiler could only warn you about a possible exception propagation, which is not an error. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-23 16:53 ` Dmitry A. Kazakov @ 2008-06-24 10:56 ` fedya_fedyakoff 2008-06-24 13:51 ` Dmitry A. Kazakov 0 siblings, 1 reply; 17+ messages in thread From: fedya_fedyakoff @ 2008-06-24 10:56 UTC (permalink / raw) > Even if it could, that would not make the program illegal. The compiler > could only warn you about a possible exception propagation, which is not an > error. Well, I thought the compiler must warn about possible exception, especially when there is such a possibility. Ok, this is just my opinion, but returning to our rams - some strangeness (an error?) is still there - consider: --- named.ads package Named is type Object is interface; function name(this: Object) return String is abstract; end Named; --- some.ads with Named; with Ada.Finalization; use Ada.Finalization; with Ada.Strings.Bounded; package Some is Size : constant := 80; package bs is new Ada.Strings.Bounded.Generic_Bounded_Length(Size); use bs; type Object is new Controlled and Named.Object with private; function Create( name: String ) return Object; overriding procedure Initialize(this: in out Object); overriding procedure Finalize(this: in out Object); overriding procedure Adjust(this: in out Object); overriding function name(this: Object) return String; private type Object is new Controlled and Named.Object with record the_name: Bounded_String; end record; end Some; --- some.adb with ada.Text_IO; with system; package body Some is package tio renames ada.Text_IO; function Create( name: String ) return Object is begin return O : Object do O.the_name := To_Bounded_String(name); end return; end Create; procedure Initialize(this: in out Object) is begin tio.Put_Line("Initialization " & this.name ); end Initialize; procedure Finalize(this: in out Object) is begin tio.Put_Line("Finalization " & this.name); end Finalize; procedure Adjust(this: in out Object) is begin tio.Put_Line("Ajusting " & this.name); end Adjust; function name(this: Object) return String is begin return To_String(this.the_name); end name; end Some; --- factory.ads with Named; package Factory is function Create(name: String) return Named.Object'Class; end Factory; --- factory.adb with Ada.Strings.Fixed; use Ada.Strings.Fixed; with Some; package body Factory is function Create(name: String) return Named.Object'Class is begin return Some.Create(name); end; end Factory; --- boom.adb with ada.Text_IO; with Named; use Named; with Factory; procedure boom is package tio renames ada.Text_IO; aNamed: Named.Object'Class := Factory.create("Some1"); begin aNamed := Factory.create("Some1"); --- *** tio.put_line( "My name is " & aNamed.name ); tio.Flush; end boom; What I can't figure out is why it's crashed at *** ? Factory creates two fully equivalent objects of the same type! Program's output looks very strange as well (at least for me) - why for two initialization we have five (!!!) finalization? It drives me crazy! The program output is as follows: Initialization Ajusting Some1 Finalization Some1 Ajusting Some1 Initialization Ajusting Some1 Finalization Some1 Finalization Some1 Finalization Some1 Finalization Some1 Execution terminated by unhandled exception Exception name: CONSTRAINT_ERROR Message: boom.adb:10 tag check failed Call stack traceback locations: 0x401b69 0x401676 0x401235 0x401286 0x7c816d4d [2008-06-24 14:51:09] process exited with status1 (elapsed time: 00.14s) ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-24 10:56 ` fedya_fedyakoff @ 2008-06-24 13:51 ` Dmitry A. Kazakov 2008-06-24 15:01 ` fedya_fedyakoff 0 siblings, 1 reply; 17+ messages in thread From: Dmitry A. Kazakov @ 2008-06-24 13:51 UTC (permalink / raw) On Tue, 24 Jun 2008 03:56:19 -0700 (PDT), fedya_fedyakoff@inbox.ru wrote: [...] > What I can't figure out is why it's crashed at *** ? Because of a compiler bug, I guess. I think you should post it. > why > for two initialization we have five (!!!) finalization? Because it should be this way. The number of Adjusts and Initializes shall match the number of Finalizes (not considering aggregates you don't have in your code). If you are familiar with C++, consider Adjust as a [part of a] copy constructor and Initialize as a [part of the] default constructor. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-24 13:51 ` Dmitry A. Kazakov @ 2008-06-24 15:01 ` fedya_fedyakoff 2008-06-24 16:31 ` Dmitry A. Kazakov 0 siblings, 1 reply; 17+ messages in thread From: fedya_fedyakoff @ 2008-06-24 15:01 UTC (permalink / raw) >Because of a compiler bug, I guess. I think you should post it. unfortunately too match bugs. > Because it should be this way. The number of Adjusts and Initializes shall > match the number of Finalizes (not considering aggregates you don't have in > your code). Oh, I see now. Thanks. > > If you are familiar with C++, consider Adjust as a [part of a] copy > constructor and Initialize as a [part of the] default constructor. I assume you mean to say as part of 'operator ='. Thanks again. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-24 15:01 ` fedya_fedyakoff @ 2008-06-24 16:31 ` Dmitry A. Kazakov 2008-06-24 16:42 ` Dmitry A. Kazakov 0 siblings, 1 reply; 17+ messages in thread From: Dmitry A. Kazakov @ 2008-06-24 16:31 UTC (permalink / raw) On Tue, 24 Jun 2008 08:01:01 -0700 (PDT), fedya_fedyakoff@inbox.ru wrote: >>Because of a compiler bug, I guess. I think you should post it. > > unfortunately too match bugs. Ada 2005 introduced stuff [e.g. limited returns], which is quite hard to implement (or merely to understand, if I dare say this (:-)). AdaCore is working hard on this. It takes time until the dust settles down... ------------------------ As a side note. The thing you are doing is quite rare. Normally nobody would assign class-wide objects. There is virtually just one case where you would need to copy (but not to overwrite!) a class-wide object: declare X : T'Class := Get_From_The_Outside_World; begin ... -- Do something with X or procedure Queue (X : T'Class) is begin Append (List, new T'Class (X)); -- Create a copy and marshal it Beyond this, class-wide objects are never assigned in the sense that you would replace one class-wide value with another. It just cannot work properly from the OO perspective because there is no static guaranty that the specific would match. If there is one, then you know the types and then you have to specify them. So at least it would be bad design. Remember that assignment is doubly dispatching. Double dispatch is not supported in Ada. Ergo, don't do that. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-24 16:31 ` Dmitry A. Kazakov @ 2008-06-24 16:42 ` Dmitry A. Kazakov 0 siblings, 0 replies; 17+ messages in thread From: Dmitry A. Kazakov @ 2008-06-24 16:42 UTC (permalink / raw) On Tue, 24 Jun 2008 18:31:12 +0200, Dmitry A. Kazakov wrote: [...] > procedure Queue (X : T'Class) is > begin > Append (List, new T'Class (X)); -- Create a copy and marshal it Append (List, new T'Class'(X)); - -Of course [...] -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-23 15:04 ` fedya_fedyakoff 2008-06-23 15:20 ` fedya_fedyakoff @ 2008-06-23 15:49 ` Adam Beneschan 2008-06-24 10:13 ` fedya_fedyakoff 1 sibling, 1 reply; 17+ messages in thread From: Adam Beneschan @ 2008-06-23 15:49 UTC (permalink / raw) On Jun 23, 8:04 am, fedya_fedyak...@inbox.ru wrote: > Hehe, and let's consider this: > > with Ada.Finalization; > procedure Test_Limited_Stuff is > > type E is ( Make_S, Make_S1 ); > > type I is interface; > > type T is new Ada.Finalization.Controlled with record > A : Integer; > end record; > > type S is new T and I with record > --Self : not null access S'Class := S'Unchecked_Access; > B: Integer; > end record; > > type S1 is new T and I with record > --Self : not null access S1'Class := S1'Unchecked_Access; > N: String(1..256); > end record; > > function Factory( w: E ) return I'Class is > begin > if w = Make_S then > return S'(Ada.Finalization.Controlled with A => 0, B => > 1); > else > return S1'(Ada.Finalization.Controlled with A => 0, N => > (others => 10) ); > end if; > end Factory; > > Value : I'Class := Factory(Make_S); > begin > Value := Factory(Make_S1); > end Test_Limited_Stuff; > > Crashed pretty badly with CONSTRAINT_ERROR, whining about tag check > error. Seems its completely buggy and unusable. You may have figured this out already, since you took back this comment. But in case you haven't... when you declare an object of type T'Class (for any tagged type T), you need to initialize it, and then whatever the specific type you initialize it to (in this case, S), the object must have that type for its whole life. You can't assign it to a new value with a different tag. You can only assign it to other values of type S. That's why you got the Tag_Error. As to whether this can be detected at compile time (as you asked in your next post): not likely, since Factory is a function whose return type is declared as I'Class; and it's too much to ask a compiler to go through the function and figure out what *specific* type it would return. Basically it would have to simulate the function's execution in order to do this. A compiler that tries to in-line the call to Factory might be able to figure this out, since the "if" condition in Factory will be known and thus the whole TRUE branch would be eliminated. But that's quite advanced. -- Adam ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-23 15:49 ` Adam Beneschan @ 2008-06-24 10:13 ` fedya_fedyakoff 0 siblings, 0 replies; 17+ messages in thread From: fedya_fedyakoff @ 2008-06-24 10:13 UTC (permalink / raw) Well, it seems using I'Class is very dangerous if I isn't limited, because it looks very match like 'dynamic typed' regarding assignment within hierarchy rooted from I... ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-23 14:21 Limited returns Dmitry A. Kazakov 2008-06-23 15:04 ` fedya_fedyakoff @ 2008-06-23 15:15 ` Adam Beneschan 2008-06-23 17:03 ` Dmitry A. Kazakov 2008-06-26 12:35 ` Egil Høvik 2 siblings, 1 reply; 17+ messages in thread From: Adam Beneschan @ 2008-06-23 15:15 UTC (permalink / raw) On Jun 23, 7:21 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> wrote: > Let's consider this: > > with Ada.Finalization; > procedure Test_Limited_Stuff is > type I is limited interface; > > type T is new Ada.Finalization.Limited_Controlled with record > A : Integer; > end record; > > type S is new T and I with record > Self : not null access S'Class := S'Unchecked_Access; > end record; > > function Factory return I'Class is > begin > return X : S; > -- GNAT: wrong type for return_subtype_indication > end Factory; > begin > null; > end Test_Limited_Stuff; > > Is it illegal? I am surprised why? S is in I'Class. It's illegal, but hopefully not for long. See: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AI05s/AI05-0032-1.TXT?rev=1.4 Perhaps you could ask your compiler to go ahead and implement that AI (or at least the part of it that allows the specific return type as you've done). I think it was just an oversight in Ada 2005 not to allow this. > OK, if that is indeed illegal, then let's make another try: > > function Factory return I'Class is > begin > return X : I'Class := S'(T with others => <>); > -- GNAT: expected an access type with designated type "S'Class" defined ... > -- found an access type with designated type "I'Class" defined ... > end Factory; > > ...still illegal, but more interesting. It seems that a Rosen's trick > member cannot be initialized because the object's type is more general than > the designated access type. It should not be so. A compiler bug? Probably. Semantically, the expression the right of := has type "S", so there shouldn't be any problem with a self-reference in that expression. However, since S is limited, the language requires the aggregate to be built in place. My guess is that when the compiler implements build-in-place in this case, it starts believing the type of the aggregate is I'Class instead of S, which leads to the wrong result. Anyway, I don't see anything illegal about this so I think it's a compiler bug. -- Adam ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-23 15:15 ` Adam Beneschan @ 2008-06-23 17:03 ` Dmitry A. Kazakov 2008-06-23 18:15 ` Adam Beneschan 0 siblings, 1 reply; 17+ messages in thread From: Dmitry A. Kazakov @ 2008-06-23 17:03 UTC (permalink / raw) On Mon, 23 Jun 2008 08:15:12 -0700 (PDT), Adam Beneschan wrote: > On Jun 23, 7:21 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> > wrote: >> Let's consider this: >> >> with Ada.Finalization; >> procedure Test_Limited_Stuff is >> type I is limited interface; >> >> type T is new Ada.Finalization.Limited_Controlled with record >> A : Integer; >> end record; >> >> type S is new T and I with record >> Self : not null access S'Class := S'Unchecked_Access; >> end record; >> >> function Factory return I'Class is >> begin >> return X : S; >> -- GNAT: wrong type for return_subtype_indication >> end Factory; >> begin >> null; >> end Test_Limited_Stuff; >> >> Is it illegal? I am surprised why? S is in I'Class. > > It's illegal, but hopefully not for long. See: > > http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AI05s/AI05-0032-1.TXT?rev=1.4 It would be nice, because this "feature" is extremely boring. > Perhaps you could ask your compiler to go ahead and implement that AI > (or at least the part of it that allows the specific return type as > you've done). I think it was just an oversight in Ada 2005 not to > allow this. Is there an AI to finally fix a similar problem with pool-specific access types? I mean this: procedure Test_Access is type T is tagged null record; type S is new T with null record; type T_Ptr is access T'Class; type S_Ptr is access S'Class; function Factory return T_Ptr is X : S_Ptr := new S; begin .. -- Do something with X return T_Ptr (X); -- Illegal!??? end Factory; begin null; end Test_Access; The only workaround is to cast: function Factory return T_Ptr is Result : P_Ptr := new S; X : S'Class renames S'Class (Result.all); begin .. -- Do something with X return Result; end Factory; -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-23 17:03 ` Dmitry A. Kazakov @ 2008-06-23 18:15 ` Adam Beneschan 2008-06-23 19:44 ` Dmitry A. Kazakov 0 siblings, 1 reply; 17+ messages in thread From: Adam Beneschan @ 2008-06-23 18:15 UTC (permalink / raw) On Jun 23, 10:03 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> wrote: > On Mon, 23 Jun 2008 08:15:12 -0700 (PDT), Adam Beneschan wrote: > > On Jun 23, 7:21 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> > > wrote: > >> Let's consider this: > > >> with Ada.Finalization; > >> procedure Test_Limited_Stuff is > >> type I is limited interface; > > >> type T is new Ada.Finalization.Limited_Controlled with record > >> A : Integer; > >> end record; > > >> type S is new T and I with record > >> Self : not null access S'Class := S'Unchecked_Access; > >> end record; > > >> function Factory return I'Class is > >> begin > >> return X : S; > >> -- GNAT: wrong type for return_subtype_indication > >> end Factory; > >> begin > >> null; > >> end Test_Limited_Stuff; > > >> Is it illegal? I am surprised why? S is in I'Class. > > > It's illegal, but hopefully not for long. See: > > >http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AI05s/AI05-0032-1.TXT?rev=1.4 > > It would be nice, because this "feature" is extremely boring. > > > Perhaps you could ask your compiler to go ahead and implement that AI > > (or at least the part of it that allows the specific return type as > > you've done). I think it was just an oversight in Ada 2005 not to > > allow this. > > Is there an AI to finally fix a similar problem with pool-specific access > types? I mean this: > > procedure Test_Access is > type T is tagged null record; > type S is new T with null record; > > type T_Ptr is access T'Class; > type S_Ptr is access S'Class; > > function Factory return T_Ptr is > X : S_Ptr := new S; > begin > .. -- Do something with X > return T_Ptr (X); -- Illegal!??? > end Factory; > begin > null; > end Test_Access; > > The only workaround is to cast: > > function Factory return T_Ptr is > Result : P_Ptr := new S; > X : S'Class renames S'Class (Result.all); > begin > .. -- Do something with X > return Result; > end Factory; I don't see an AI for this. I'm guessing that the problem would be that you could specify different pools for the two different access types, which would make the type conversion problematic (you'd have an access type object that points into the wrong pool, which could then cause havoc if you do an Unchecked_Deallocation). If the language rules said that a type conversion like this were allowed only if the storage pools were the same, the problem would then be that, since a storage pool rep clause could appear in the private part of a package, you could have a situation where you could not tell whether a type conversion was legal without peeking into the private part of a package you don't have visibility to. And that's something the language designers try very hard to avoid. On the other hand, if you're not going to specify a Storage_Pool for the types, is there a reason to make them pool-specific? I'm not sure what's gained by doing so. -- Adam ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-23 18:15 ` Adam Beneschan @ 2008-06-23 19:44 ` Dmitry A. Kazakov 0 siblings, 0 replies; 17+ messages in thread From: Dmitry A. Kazakov @ 2008-06-23 19:44 UTC (permalink / raw) On Mon, 23 Jun 2008 11:15:23 -0700 (PDT), Adam Beneschan wrote: > On Jun 23, 10:03 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> > wrote: >> >> Is there an AI to finally fix a similar problem with pool-specific access >> types? I mean this: >> >> procedure Test_Access is >> type T is tagged null record; >> type S is new T with null record; >> >> type T_Ptr is access T'Class; >> type S_Ptr is access S'Class; >> >> function Factory return T_Ptr is >> X : S_Ptr := new S; >> begin >> .. -- Do something with X >> return T_Ptr (X); -- Illegal!??? >> end Factory; >> begin >> null; >> end Test_Access; >> >> The only workaround is to cast: >> >> function Factory return T_Ptr is >> Result : P_Ptr := new S; >> X : S'Class renames S'Class (Result.all); >> begin >> .. -- Do something with X >> return Result; >> end Factory; > > I don't see an AI for this. I'm guessing that the problem would be > that you could specify different pools for the two different access > types, which would make the type conversion problematic (you'd have an > access type object that points into the wrong pool, which could then > cause havoc if you do an Unchecked_Deallocation). Clearly the conversion should simply raise Constraint_Error when pools aren't same. > If the language > rules said that a type conversion like this were allowed only if the > storage pools were the same, the problem would then be that, since a > storage pool rep clause could appear in the private part of a package, > you could have a situation where you could not tell whether a type > conversion was legal without peeking into the private part of a > package you don't have visibility to. And that's something the > language designers try very hard to avoid. It is just like with tags, they too cannot be always statically checked. > On the other hand, if you're not going to specify a Storage_Pool for > the types, is there a reason to make them pool-specific? I'm not sure > what's gained by doing so. 1. Safety. It guarantees no objects on the stack. 2. If an access type is a generic parameter, then to have it general access is a stronger precondition than necessary. It would be a bad design. 3. There are important cases when pools are needed. For example, to have a container of indefinite by-value objects. If you don't want the overhead of lists of descriptors, a custom pool is the just the way. (In some cases streams would also work, but pools are more universal and efficient) 4. Pool-specific access could be more efficient. ------------ There is a related problem, that when a pool-specific object is initialized or finalized, there is no way to get a pool-specific access to it. One have to use Unchecked_Conversion of a general access type, which is not even guaranteed to work. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-23 14:21 Limited returns Dmitry A. Kazakov 2008-06-23 15:04 ` fedya_fedyakoff 2008-06-23 15:15 ` Adam Beneschan @ 2008-06-26 12:35 ` Egil Høvik 2008-06-26 14:12 ` Dmitry A. Kazakov 2 siblings, 1 reply; 17+ messages in thread From: Egil Høvik @ 2008-06-26 12:35 UTC (permalink / raw) On Jun 23, 4:21 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> wrote: > Let's consider this: > > with Ada.Finalization; > procedure Test_Limited_Stuff is > type I is limited interface; > > type T is new Ada.Finalization.Limited_Controlled with record > A : Integer; > end record; > > type S is new T and I with record > Self : not null access S'Class := S'Unchecked_Access; > end record; > > function Factory return I'Class is > begin > return X : S; > -- GNAT: wrong type for return_subtype_indication > end Factory; > begin > null; > end Test_Limited_Stuff; > > Is it illegal? I am surprised why? S is in I'Class. > > OK, if that is indeed illegal, then let's make another try: > > function Factory return I'Class is > begin > return X : I'Class := S'(T with others => <>); > -- GNAT: expected an access type with designated type "S'Class" defined ... > -- found an access type with designated type "I'Class" defined ... > end Factory; > > ...still illegal, but more interesting. It seems that a Rosen's trick > member cannot be initialized because the object's type is more general than > the designated access type. It should not be so. A compiler bug? > > -- > Regards, > Dmitry A. Kazakovhttp://www.dmitry-kazakov.de If the goal is to make this compile, do this: function Factory return I'Class is function S_Factory return S is begin return X : S; end S_Factory; begin return X : I'Class := S_Factory; end Factory; But then it seems that dispatching on methods of I is broken... (at least I couldn't get it to work with an abstract procedure. Didn't dispatch to the overridden procedure implemented by S or give an error...) ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Limited returns 2008-06-26 12:35 ` Egil Høvik @ 2008-06-26 14:12 ` Dmitry A. Kazakov 0 siblings, 0 replies; 17+ messages in thread From: Dmitry A. Kazakov @ 2008-06-26 14:12 UTC (permalink / raw) On Thu, 26 Jun 2008 05:35:34 -0700 (PDT), Egil H�vik wrote: > But then it seems that dispatching on methods of I is broken... > (at least I couldn't get it to work with an abstract procedure. I think this too is related to the bug I have already reported to AdaCore. The object X will be prematurely finalized. This might mangle dispatching stuff, if it does not crash immediately. We should wait for a fix. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2008-06-26 14:12 UTC | newest] Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-06-23 14:21 Limited returns Dmitry A. Kazakov 2008-06-23 15:04 ` fedya_fedyakoff 2008-06-23 15:20 ` fedya_fedyakoff 2008-06-23 16:53 ` Dmitry A. Kazakov 2008-06-24 10:56 ` fedya_fedyakoff 2008-06-24 13:51 ` Dmitry A. Kazakov 2008-06-24 15:01 ` fedya_fedyakoff 2008-06-24 16:31 ` Dmitry A. Kazakov 2008-06-24 16:42 ` Dmitry A. Kazakov 2008-06-23 15:49 ` Adam Beneschan 2008-06-24 10:13 ` fedya_fedyakoff 2008-06-23 15:15 ` Adam Beneschan 2008-06-23 17:03 ` Dmitry A. Kazakov 2008-06-23 18:15 ` Adam Beneschan 2008-06-23 19:44 ` Dmitry A. Kazakov 2008-06-26 12:35 ` Egil Høvik 2008-06-26 14:12 ` Dmitry A. Kazakov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox