[net.lang.ada] subaggregates???

Mendal@SU-SIERRA.ARPA (Geoff Mendal) (02/09/86)

Hi all,

We have a question concerning subaggregates.  Consider the following
program...

	procedure Agg is
	    type R is
		record
		    X : String (1 .. 2) := (others => 'z');
		    Y : String (5 .. 6) := (others => 'z');
		end record;
	     A : R;
	begin
	    A := (others => (others => 'a'));
	    A := (X | Y => (others => 'a'));
	    A := ((others => 'c'), (others => 'c'));
	end Agg;

Now the question is:  Should any of these assignments raise
Constraint_Error?  The Data General raises Constraint_Error on the
first two but not on the third.   Is the subaggregate
	(others => 'a')
in the first (and second) assignment evaluated once or twice?
Do things change if the components X and Y are of different lengths?



thanks in advance to anybody who has the slightest idea,

doug bryan   and    Geoff Mendal
-------

jon@shell.UUCP (Jon M. Holdman) (02/11/86)

Geoff Mendal writes:
>	procedure Agg is
>	    type R is
>		record
>		    X : String (1 .. 2) := (others => 'z');
>		    Y : String (5 .. 6) := (others => 'z');
>		end record;
>	     A : R;
>	begin
>	    A := (others => (others => 'a'));
>	    A := (X | Y => (others => 'a'));
>	    A := ((others => 'c'), (others => 'c'));
>	end Agg;
>
>Now the question is:  Should any of these assignments raise
>Constraint_Error?  The Data General raises Constraint_Error on the
>first two but not on the third. 

I tried this on the Verdix compiler, and got the same result as the
Data General.  I dug through the LRM, and found the following passage
which (I think) explains why Verdix and Data General are correct:

LRM 4.3.1 Paragraph 1:
   ... A component association with the choice others ( your case 1 )
   or with more than one choice ( your case 2 ) is only allowed if the
   represented components are all of the same type. ...

The X and Y components of your record are (implicitly) of different
types (as defined by LRM 3.6, paragraphs 14-17, especially 17), 
so your first and second examples are illegal.  Why it gives
a CONSTRAINT_ERROR is not entirely clear to me.  I guess the compiler
picks one of the two string types, and then gets the exception when
it tries to assign it to the other type.

>                                  Is the subaggregate
>	(others => 'a')
>in the first (and second) assignment evaluated once or twice?

The LRM also states (4.3.1 Paragraph 3) "... The expression of a named 
association is evaluated once for each associated component."  They 
give an example of a binary tree node aggregrate:
   ( Value => 0, Succ|Pred => new Cell'(O,null,null) )
and point out that the new operation is executed twice, once for Succ,
and once for Pred.

>Do things change if the components X and Y are of different lengths?

No, I don't think so.  The two components are already of different types,
so the exact indices and length of the strings don't really matter.
I did try the example as follows:

	procedure Agg is
	    type R is
		record
		    X : String (1 .. 2) := (others => 'z');
		    Y : String (1 .. 2) := (others => 'z');
		end record;
	     A : R;
	begin
	    A := (others => (others => 'a'));
	    A := (X | Y => (others => 'a'));
	    A := ((others => 'c'), (others => 'c'));
	end Agg;

This works ok, which I did not expect.  I'm not sure why.  I guess in this
case, the compiler still picks one of the two types, and this time, when 
it assigns it to the component of the other type, it works ok.  I wonder 
if both compilers should have an additional check (at compile time?)
to verify the first sentence quoted above.  That is, should the compiler
explicitly check the types when others or multiple components are used?

By the way, I'm posting this to net.lang.ada on USENET.  Do you folks
on ARPANET see this?

Jon M. Holdman, Shell Development Co.
UUCP: ...{ihnp4, ut-sally, pur-ee}!shell!jon
ARPA: "ihnp4!shell!jon"@Berkeley.ARPA         -- I'm not sure this is right