comp.lang.ada
 help / color / mirror / Atom feed
* Dynamic allocation of unconstrained types
@ 2009-09-30 14:29 Maciej Sobczak
  2009-09-30 14:50 ` Robert A Duff
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Maciej Sobczak @ 2009-09-30 14:29 UTC (permalink / raw)


Consider:

procedure Test is

   package P is
      type T (<>) is limited private;
      function Create return T;
   private
      type T is limited record
         I : Integer;
      end record;
   end P;

   package body P is
      function Create return T is
      begin
         return T'(I => 123);
      end Create;
   end P;

   S : access P.T;

begin
   S := new P.T'(P.Create);   -- ??? (this is line 22)
end Test;

GNAT says:

test.adb:22:19: uninitialized unconstrained allocation not allowed
test.adb:22:19: qualified expression required

Interestingly, it works with Strings.
Why doesn't GNAT recognize it as a qualified expression?

I would like to allocate dynamically something that has a constructor
function. There is no other way to create the object than with that
function and presumably it should be possible to use it with dynamic
allocation.
How can I do it?

BTW - when preparing this example I tried first with empty (null)
record, but got stuck with proper way to return an instance of T. I
remember there was some older discussion about it, but for some reason
I cannot find it and the following:

return T'(others => <>);

is rejected as well.
What is the proper way to create null aggregates?

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Dynamic allocation of unconstrained types
  2009-09-30 14:29 Dynamic allocation of unconstrained types Maciej Sobczak
@ 2009-09-30 14:50 ` Robert A Duff
  2009-09-30 14:54 ` Adam Beneschan
  2009-09-30 14:56 ` Dmitry A. Kazakov
  2 siblings, 0 replies; 7+ messages in thread
From: Robert A Duff @ 2009-09-30 14:50 UTC (permalink / raw)


Maciej Sobczak <see.my.homepage@gmail.com> writes:

> procedure Test is
>
>    package P is
>       type T (<>) is limited private;
>       function Create return T;
>    private
>       type T is limited record
>          I : Integer;
>       end record;
>    end P;
>
>    package body P is
>       function Create return T is
>       begin
>          return T'(I => 123);
>       end Create;
>    end P;
>
>    S : access P.T;

I try to avoid the use of anonymous access types.
They cause too many surprises.

> begin
>    S := new P.T'(P.Create);   -- ??? (this is line 22)
> end Test;
>
> GNAT says:
>
> test.adb:22:19: uninitialized unconstrained allocation not allowed
> test.adb:22:19: qualified expression required

Looks like a bug in the compiler.

> Interestingly, it works with Strings.
> Why doesn't GNAT recognize it as a qualified expression?
>
> I would like to allocate dynamically something that has a constructor
> function. There is no other way to create the object than with that
> function and presumably it should be possible to use it with dynamic
> allocation.
> How can I do it?
>
> BTW - when preparing this example I tried first with empty (null)
> record, but got stuck with proper way to return an instance of T. I
> remember there was some older discussion about it, but for some reason
> I cannot find it and the following:
>
> return T'(others => <>);

    return (null record);

or 

    return T'(null record);

The "others => <>" should work, too.

> is rejected as well.
> What is the proper way to create null aggregates?

- Bob



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Dynamic allocation of unconstrained types
  2009-09-30 14:29 Dynamic allocation of unconstrained types Maciej Sobczak
  2009-09-30 14:50 ` Robert A Duff
@ 2009-09-30 14:54 ` Adam Beneschan
  2009-09-30 18:30   ` Jeffrey R. Carter
  2009-09-30 14:56 ` Dmitry A. Kazakov
  2 siblings, 1 reply; 7+ messages in thread
From: Adam Beneschan @ 2009-09-30 14:54 UTC (permalink / raw)


On Sep 30, 7:29 am, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
> Consider:
>
> procedure Test is
>
>    package P is
>       type T (<>) is limited private;
>       function Create return T;
>    private
>       type T is limited record
>          I : Integer;
>       end record;
>    end P;
>
>    package body P is
>       function Create return T is
>       begin
>          return T'(I => 123);
>       end Create;
>    end P;
>
>    S : access P.T;
>
> begin
>    S := new P.T'(P.Create);   -- ??? (this is line 22)
> end Test;
>
> GNAT says:
>
> test.adb:22:19: uninitialized unconstrained allocation not allowed
> test.adb:22:19: qualified expression required
>
> Interestingly, it works with Strings.
> Why doesn't GNAT recognize it as a qualified expression?

It looks like a bug to me.  I do notice that if you remove "limited"
from both declarations of T, then it works.  There are some new Ada
2005 rules that allow limited-type expressions in more places
(functions returning limited types weren't allowed in Ada 95), so it's
likely that there was a mistake in implementing this new feature.


> I would like to allocate dynamically something that has a constructor
> function. There is no other way to create the object than with that
> function and presumably it should be possible to use it with dynamic
> allocation.
> How can I do it?
>
> BTW - when preparing this example I tried first with empty (null)
> record, but got stuck with proper way to return an instance of T. I
> remember there was some older discussion about it, but for some reason
> I cannot find it and the following:
>
> return T'(others => <>);
>
> is rejected as well.

Try

   return T'(null record);

The first attempt, with (others => <>), should have worked, but there
was faulty language in the RM that made this illegal for a null
record.  It has been fixed by a Binding Interpretation, AI05-16, so I
think compilers should allow that construct, but perhaps it hasn't yet
been fixed in the version of GNAT you're using.

                                   -- Adam



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Dynamic allocation of unconstrained types
  2009-09-30 14:29 Dynamic allocation of unconstrained types Maciej Sobczak
  2009-09-30 14:50 ` Robert A Duff
  2009-09-30 14:54 ` Adam Beneschan
@ 2009-09-30 14:56 ` Dmitry A. Kazakov
  2009-09-30 15:03   ` Adam Beneschan
  2 siblings, 1 reply; 7+ messages in thread
From: Dmitry A. Kazakov @ 2009-09-30 14:56 UTC (permalink / raw)


On Wed, 30 Sep 2009 07:29:26 -0700 (PDT), Maciej Sobczak wrote:

> Consider:
> 
> procedure Test is
> 
>    package P is
>       type T (<>) is limited private;
>       function Create return T;
>    private
>       type T is limited record
>          I : Integer;
>       end record;
>    end P;
> 
>    package body P is
>       function Create return T is
>       begin
>          return T'(I => 123);
>       end Create;
>    end P;
> 
>    S : access P.T;
> 
> begin
>    S := new P.T'(P.Create);   -- ??? (this is line 22)
> end Test;
> 
> GNAT says:
> 
> test.adb:22:19: uninitialized unconstrained allocation not allowed
> test.adb:22:19: qualified expression required
> 
> Interestingly, it works with Strings.

Because String is not a limited type.

> Why doesn't GNAT recognize it as a qualified expression?

Qualified expression is not allowed for a limited types, logically. (Not
yet, I think it will be a necessary step in order to continue the idea of
limited aggregates. Once we allowed them, there is no reason not to allow
qualified aggregates and thus limited expressions. After all aggregate is
an expression. Language design bugs are always punished in the end...)
 
> I would like to allocate dynamically something that has a constructor
> function. There is no other way to create the object than with that
> function and presumably it should be possible to use it with dynamic
> allocation.
> How can I do it?

By providing a function that explicitly returns an access to T.

What you are trying to do: is to enforce a custom initialization on a
limited private type. That does not work in Ada, alas. It is hopeless, I am
afraid. The best way I know is to make it public, removing the indefinite
constraint. Otherwise you will get mounting problems crippling your design
more and more, and still get no working solution.

> BTW - when preparing this example I tried first with empty (null)
> record, but got stuck with proper way to return an instance of T. I
> remember there was some older discussion about it, but for some reason
> I cannot find it and the following:
> 
> return T'(others => <>);
> 
> is rejected as well.
> What is the proper way to create null aggregates?

   return (null record);

if you need to specify the type, like when the formal result is class-wide,
then:

   return X : T;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Dynamic allocation of unconstrained types
  2009-09-30 14:56 ` Dmitry A. Kazakov
@ 2009-09-30 15:03   ` Adam Beneschan
  0 siblings, 0 replies; 7+ messages in thread
From: Adam Beneschan @ 2009-09-30 15:03 UTC (permalink / raw)


On Sep 30, 7:56 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Wed, 30 Sep 2009 07:29:26 -0700 (PDT), Maciej Sobczak wrote:
> > Consider:
>
> > procedure Test is
>
> >    package P is
> >       type T (<>) is limited private;
> >       function Create return T;
> >    private
> >       type T is limited record
> >          I : Integer;
> >       end record;
> >    end P;
>
> >    package body P is
> >       function Create return T is
> >       begin
> >          return T'(I => 123);
> >       end Create;
> >    end P;
>
> >    S : access P.T;
>
> > begin
> >    S := new P.T'(P.Create);   -- ??? (this is line 22)
> > end Test;
>
> > GNAT says:
>
> > test.adb:22:19: uninitialized unconstrained allocation not allowed
> > test.adb:22:19: qualified expression required
>
> > Interestingly, it works with Strings.
>
> Because String is not a limited type.
>
> > Why doesn't GNAT recognize it as a qualified expression?
>
> Qualified expression is not allowed for a limited types, logically.

Yes, they are; see 7.5(2.1-2.9).

                                -- Adam



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Dynamic allocation of unconstrained types
  2009-09-30 14:54 ` Adam Beneschan
@ 2009-09-30 18:30   ` Jeffrey R. Carter
  2009-09-30 19:15     ` Adam Beneschan
  0 siblings, 1 reply; 7+ messages in thread
From: Jeffrey R. Carter @ 2009-09-30 18:30 UTC (permalink / raw)


Adam Beneschan wrote:
> 
> (functions returning limited types weren't allowed in Ada 95)

Yes, they were.

The current revision changed them significantly.

-- 
Jeff Carter
"We use a large, vibrating egg."
Annie Hall
44



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Dynamic allocation of unconstrained types
  2009-09-30 18:30   ` Jeffrey R. Carter
@ 2009-09-30 19:15     ` Adam Beneschan
  0 siblings, 0 replies; 7+ messages in thread
From: Adam Beneschan @ 2009-09-30 19:15 UTC (permalink / raw)


On Sep 30, 11:30 am, "Jeffrey R. Carter"
<spam.jrcarter....@spam.acm.org> wrote:
> Adam Beneschan wrote:
>
> > (functions returning limited types weren't allowed in Ada 95)
>
> Yes, they were.

Oh, yeah, that's right---the return-by-reference thing.  I forgot
about that because they were really more like functions that return an
access to some existing object, rather than functions returning an
object.  You couldn't create a new limited object and return it.
Anyway, that doesn't really affect my point: the compiler's
implementation of functions returning limited types is pretty much all
new for Ada 2005, and this appears to be a case that slipped through
the cracks in GNAT.

                                   -- Adam



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2009-09-30 19:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-30 14:29 Dynamic allocation of unconstrained types Maciej Sobczak
2009-09-30 14:50 ` Robert A Duff
2009-09-30 14:54 ` Adam Beneschan
2009-09-30 18:30   ` Jeffrey R. Carter
2009-09-30 19:15     ` Adam Beneschan
2009-09-30 14:56 ` Dmitry A. Kazakov
2009-09-30 15:03   ` Adam Beneschan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox