comp.lang.ada
 help / color / mirror / Atom feed
* 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 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: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: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: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 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 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 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 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