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