comp.lang.ada
 help / color / mirror / Atom feed
* Forcing default representations
@ 1993-07-13 19:22 crispen
  0 siblings, 0 replies; 12+ messages in thread
From: crispen @ 1993-07-13 19:22 UTC (permalink / raw)


OK, just what the hell does LRM 13.1(6) mean, anyway?

"certain occurrences of its name imply that the representation of the
type must have been determined."

Even the Annotated LRM is obscure on this point. "certain occurrences"
indeed!

My goal here is to put as many of my rep specs as I possibly can in
a private part.  In fact, I've been making some really sexy rep specs:

   for Trim_Max_Rate use
    record
      Aircraft_Trim_Positions
         at 0
         range 0..Aircraft_Trim_Position_Array_Size-1;
      Surface_Tab_Deflections
         at Aircraft_Trim_Position_Array_Size/8
         range 0..Surface_Tab_Deflection_Array_Size-1;
    end record;
   for Trim_Max_Rate'size use
      Aircraft_Trim_Position_Array_Size +
      Surface_Tab_Deflection_Array_Size;

Where I've defined the _Size constants elsewhere, e.g.:

   Aircraft_Trim_Position_Array_Size : constant :=
      Number_Of_Aircraft_Trims * Float_Size;
   for Aircraft_Trim_Position_Array'size use
      Aircraft_Trim_Position_Array_Size;

Like I said, pure sex -- oh, yeah, naturally I define:

   Number_Of_Aircraft_Trims : constant :=
      Aircraft_Trim'pos (Aircraft_Trim'last) -
      Aircraft_Trim'pos (Aircraft_Trim'first) + 1;

So basically I'm going after having the best of all possible worlds:
we have rep specs (essential, because we're defining objects that are
going on a network between two machines of possibly different
architectures), but the person who is modifying this file should
be able to add or delete from the Aircraft_Trim enumeration at will,
and the rep specs are generated automatically.  Cool!

In fact, I've tested this out on a SPARC, a 68030 board, and an
SGI Indigo, and it works!  Or, at any rate, when I define an object
of the type and have Text_IO put out the object'size/8 it gives
the same answer on all 3 machines.

The problem, though, is with this declaration:

   type Flight_Controls_Discrete_Outputs is (
      Flt_Control_System_Caution_Light,
      LE_Flaps_Caution_Light [...]

   Flight_Controls_Discrete_Outputs_Size : constant := 8;
   for Flight_Controls_Discrete_Outputs'size use
      Flight_Controls_Discrete_Outputs_Size;

If I define this above the private part, and before the declaration:

   type Flight_Controls_Discrete_Data_Pair is
   record
      Name  : Flight_Controls_Discrete_Outputs;
      State : Base_Types.Discrete_State;
    end record;

no problem.  If I don't, and if I define it in the private part, then
I get the following error:

/usr/people/crispen/generic/types/fc_if_types.a, line 372, char 5:error: RM 13.
1(6): type representation already determined by a forcing occurrence

on all 3 of my Ada compilers (they're VADS, but of different vintages).

But, I can define this record:

   for Landing_Gear_Parameters use
    record
      Position   at 0 range Four_Bytes;
      State      at 4 range One_Byte;
      -- 3 bytes spare
      Crab_Angle at 8 range Four_Bytes;
    end record;
   Landing_Gear_Parameters_Size : constant := 12 * Bytes;
   for Landing_Gear_Parameters'size use Landing_Gear_Parameters_Size;

in the private part with no problems (and Landing_Gear_Parameters is
defined as an element of another record before the private part).
You'd think that if one was a problem, so would the other one be,
but Nooooooo!

So, is my compiler ignoring the rep specs in the private part, or
what?

p.s.: I know I should substitute System.Storage_Unit for "8" above,
and I will.

p.p.s: I've defined:

   type One_Byte is range 0..7;
   type Two_Bytes is range 0..15;
   type Three_Bytes is range 0..23;
   type Four_Bytes is range 0..31;

Cute trick, eh?
+-------------------------------+--------------------------------------+
| Bob Crispen                   |   Who will babysit the babysitters?  |
| crispen@foxy.boeing.com       +--------------------------------------+
| (205) 461-3296                |Opinions expressed here are mine alone|
+-------------------------------+--------------------------------------+

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

* Re: Forcing default representations
@ 1993-07-16 22:26 dog.ee.lbl.gov!overload.lbl.gov!agate!howland.reston.ans.net!noc.near.net
  0 siblings, 0 replies; 12+ messages in thread
From: dog.ee.lbl.gov!overload.lbl.gov!agate!howland.reston.ans.net!noc.near.net @ 1993-07-16 22:26 UTC (permalink / raw)


In article <9307131922.AA04017@eight-ball.boeing.com> 
  crispen@eight-ball.boeing.com (crispen) writes:

>OK, just what the hell does LRM 13.1(6) mean, anyway?
>
>"certain occurrences of its name imply that the representation of the
>type must have been determined."
>
>Even the Annotated LRM is obscure on this point. "certain occurrences"
>indeed!

The "certain occurrences" are called "forcing occurrences" in
Ada 83 parlance ("freezing points" in Ada 9X).  These are points
at which a representation is chosen by default if you haven't
specified it explicitly.  After a forcing occurrence of the
name of an entity, it is *illegal* to give a representation clause for the 
entity.

The most common forcing occurrence for a type is a declaration
of an object of the type (or an object of a composite type that 
has a subcomponent of the type).  Declaring subprograms or
composite types are *not* forcing occurrences for their parameter or
component types.

For discrete types, using the type as an index type for an
array type is a forcing occurrence.

There are other more obscure forcing occurrences, but if you
are lucky, you didn't run into one of those...

>My goal here is to put as many of my rep specs as I possibly can in
>a private part.  . . .

Although this seems like a noble goal, there are Ada gurus who
would recommend against this strategy, since it means you have to
worry about this silly "forcing occurrence" stuff.
Particularly for scalar types, I would also recommend that 
the rep clauses follow the type declaration immediately.

> . . .
>The problem, though, is with this declaration:
>
>   type Flight_Controls_Discrete_Outputs is (
>      Flt_Control_System_Caution_Light,
>      LE_Flaps_Caution_Light [...]
>
>   Flight_Controls_Discrete_Outputs_Size : constant := 8;
>   for Flight_Controls_Discrete_Outputs'size use
>      Flight_Controls_Discrete_Outputs_Size;
>
>If I define this above the private part, and before the declaration:
>
>   type Flight_Controls_Discrete_Data_Pair is
>   record
>      Name  : Flight_Controls_Discrete_Outputs;
>      State : Base_Types.Discrete_State;
>    end record;
>
>no problem.  If I don't, and if I define it in the private part, then
>I get the following error:
>
>/usr/people/crispen/generic/types/fc_if_types.a, line 372, char 5:error: RM 13
.1(6): type representation already determined by a forcing occurrence
>
>on all 3 of my Ada compilers (they're VADS, but of different vintages).

Using a type in the definition of another type is *not*
a forcing occurrence.  Either all your compilers have the same
bug, or you have a declaration of an object of type 
Flight_Controls_Discrete_Data_Pair (or some other forcing occurence
for that type, or something that includes that type as a component).
The real problem may be that the error message is not identifying
the forcing occurrence that "forced" the representation of your type.
It rather points at the rep-clause, but your problem is that you
don't know where is the forcing occurrence.

Remember that forcing occurrences are "recursive," in that they
force the type, and all of the subcomponent types as well.

> . . .
>| Bob Crispen                   |   Who will babysit the babysitters?  |
>| crispen@foxy.boeing.com       +--------------------------------------+

Hope that helps...

S. Tucker Taft
Intermetrics, Inc.
Cambridge, MA  02138

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

* Re: Forcing default representations
@ 1993-07-19 16:56 Adam Beneschan
  0 siblings, 0 replies; 12+ messages in thread
From: Adam Beneschan @ 1993-07-19 16:56 UTC (permalink / raw)


In article <9307131922.AA04017@eight-ball.boeing.com> 
crispen@eight-ball.boeing.com (crispen) writes:

[stuff deleted]

>   But, I can define this record:
>
>      for Landing_Gear_Parameters use
>       record
>         Position   at 0 range Four_Bytes;
>         State      at 4 range One_Byte;
>         -- 3 bytes spare
>         Crab_Angle at 8 range Four_Bytes;
>       end record;
>      Landing_Gear_Parameters_Size : constant := 12 * Bytes;
>      for Landing_Gear_Parameters'size use Landing_Gear_Parameters_Size;
>
[more stuff deleted]
>   p.p.s: I've defined:
>
>      type One_Byte is range 0..7;
>      type Two_Bytes is range 0..15;
>      type Three_Bytes is range 0..23;
>      type Four_Bytes is range 0..31;
>
>   Cute trick, eh?

Is this cute trick actually legal?  The LRM defines

    component_clause ::= COMPONENT_name at STATIC_simple_expression
       range STATIC_range;           [13.4(2)]

    range ::= RANGE_attribute | simple_expression .. simple_expression
                                     [3.5(2)]

I don't see how a type name fits into the component clause of a record
rep clause, given these syntax definitions.  Am I missing something
somewhere else in the LRM?  Or is there an AI that allows this trick?

                                -- thanks, Adam

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

* Re: Forcing default representations
@ 1993-07-20 12:57 Bob Crispen
  0 siblings, 0 replies; 12+ messages in thread
From: Bob Crispen @ 1993-07-20 12:57 UTC (permalink / raw)


Adam Beneschan queries the legality of the following:

>      type One_Byte is range 0..7;
>      type Four_Bytes is range 0..31;

>      for Landing_Gear_Parameters use
>       record
>         Position   at 0 range Four_Bytes;
>         State      at 4 range One_Byte;
>       end record;

and another correspondent who hasn't given me permission to quote
him says that his Alsys Ada compiler won't compile the code above,
while all 3 of my VADS compilers (of different vintages, and for
different targets) will.

What I had in mind of course was analogous to the universal practice:

	type Colors is (Mauve, Puce, Ultraviolet);
	for Each_Color in Colors loop


"in Colors" being shorthand for "in Colors'first..Colors'last".  I
believe every Ada compiler accepts this, but I can't find the
LRM entry that says where it has to.  Probably right under my nose.

So, here's the question -- whose compiler has the bug in it?  Or have
I, in my quest to write portable code, ended up writing non-portable
code?  If you pick the latter, please say why!
+-------------------------------+--------------------------------------+
| Bob Crispen                   |   Who will babysit the babysitters?  |
| crispen@foxy.boeing.com       +--------------------------------------+
| (205) 461-3296                |Opinions expressed here are mine alone|
+-------------------------------+--------------------------------------+

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

* Re: Forcing default representations
@ 1993-07-22 18:34 Bob Crispen
  0 siblings, 0 replies; 12+ messages in thread
From: Bob Crispen @ 1993-07-22 18:34 UTC (permalink / raw)


Tucker Taft sez:

>For discrete types, using the type as an index type for an
>array type is a forcing occurrence.

Yup.  I did use it as an index elsewhere, but I thought it was the
thing I gave in my example.  No compiler bug.  Thanks for the
clarification, and I appreciate the trouble.

I certainly understand why the internal values of an enumeration
are frozen when it's used as an index, but not quite sure why its
size is frozen if the array type is constrained.  Oh, well.

By the way, here's a semi-trivial question:  Does anyone know of
a real Ada compiler that doesn't assign internal values of integers
(forget the size for a minute) beginning with zero as a default for
enumerations?  I know you can't rely on it, but is there actually
a compiler or a machine that doesn't do it the obvious way?

It's a pity that we have to put some rep specs in the public part,
since in our case the interface type declarations and object
declarations form the IDD for our program.  We could take a pair
of scissors to those source code listings at the word "private"
with a clear conscience and have one hell of a readable document.

And, definitely non-trivially, can someone explain why some compilers
approve of (and even generate proper code for) the following:

	type Four_Bytes is range 0..31;
	...
	for X use
         record
           Y at 0 range Four_Bytes;
           ...
        end record;

and some don't?
+----------------------------+-----------------------------------------+
| Bob Crispen                | You guys start coding.  I'll go see     |
| crispen@foxy.boeing.com    | what they want.                         |
+----------------------------+-----------------------------------------+

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

* Re: Forcing default representations
@ 1993-07-23 19:15 Gary Morris @ignite
  0 siblings, 0 replies; 12+ messages in thread
From: Gary Morris @ignite @ 1993-07-23 19:15 UTC (permalink / raw)


In <9307221834.AA03070@eight-ball.boeing.com> crispen@eight-ball.boeing.com (Bo
b Crispen) writes:
>By the way, here's a semi-trivial question:  Does anyone know of
>a real Ada compiler that doesn't assign internal values of integers
>(forget the size for a minute) beginning with zero as a default for
>enumerations?  

I suspect all compilers would assign internal values that match the
position number, doing something different would impact the performance
of the 'pos operation since the position number is required to start at
zero (LRM 3.5.1 p4).

The only exception I've ever seen was a TeleSoft compiler that used internal
values of 0 and -1 for Boolean, with the corresponding position numbers of 0
and 1.  This was for a MC680X0 processor and boolean operations were more
efficient by making True have an internal value of -1. 

--GaryM
-- 
Gary Morris                      Internet: garym@alsys.com
TeleUSE/Ada Development          UUCP:     uunet!alsys.com!garym
Alsys Inc. (TeleSoft)            Phone:    +1 619-457-2700 x128
San Diego, CA, USA               Fax:      +1 619-452-1334

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

* Re: Forcing default representations
@ 1993-07-24 17:13 pipex!sunic!news.funet.fi!funic!news.eunet.fi!prime!mits!rkaivola
  0 siblings, 0 replies; 12+ messages in thread
From: pipex!sunic!news.funet.fi!funic!news.eunet.fi!prime!mits!rkaivola @ 1993-07-24 17:13 UTC (permalink / raw)


crispen@eight-ball.boeing.com (Bob Crispen) writes:

>And, definitely non-trivially, can someone explain why some compilers
>approve of (and even generate proper code for) the following:

>	type Four_Bytes is range 0..31;
>	...
>	for X use
>         record
>           Y at 0 range Four_Bytes;
>           ...
>        end record;

>and some don't?
> Bob Crispen 

I think that a compiler that accepts this is definitely broken.
According to the relevant chapter (13.4) of the RM, a component
clause is defined as (omitting the italicised prefixes which do
not reflect any syntactic categories, but are there to provide
information to the human reader)

component_clause ::= name AT simple_expression RANGE range;

In 3.5 we find that (again substituting attribute for <range>_attribute)

range ::= attribute | simple_expression .. simple_expression

Actually, according to AI-00498, a range attribute is not allowed
in a component clause, and this fact is reflected in the Annotated
Ada Reference Manual for Ada9X.  But in your example, Four_Bytes
does not even fall into the syntactic category attribute!  I wonder
what the bug causing this behaviour is.  Probably the implementation
simplifies its job by sort-of 'reusing' some of the code it uses in
other situations of this sort, erroneusly.

--
Risto Kaivola
(Internet address:   rkaivola@mits.mdata.fi)

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

* Re: Forcing default representations
@ 1993-07-24 21:16 Erik Magnuson
  0 siblings, 0 replies; 12+ messages in thread
From: Erik Magnuson @ 1993-07-24 21:16 UTC (permalink / raw)


In article <9307221834.AA03070@eight-ball.boeing.com> crispen@eight-ball.boeing
.com (Bob Crispen) writes:
>By the way, here's a semi-trivial question:  Does anyone know of
>a real Ada compiler that doesn't assign internal values of integers
>(forget the size for a minute) beginning with zero as a default for
>enumerations?  I know you can't rely on it, but is there actually
>a compiler or a machine that doesn't do it the obvious way?

What gets my goat is that there are still compilers marketed for
embedded systems that do not recognize when a enumeration rep spec
repeats the canonical values that they do not have to generate the
(expensive) code to translate between the values!

-- 
Erik

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

* Re: Forcing default representations
@ 1993-07-26 15:12 agate!howland.reston.ans.net!europa.eng.gtefsd.com!news.ans.net!newsgate.watson.ibm.com!yktnews.watson.ibm.com!ncohen
  0 siblings, 0 replies; 12+ messages in thread
From: agate!howland.reston.ans.net!europa.eng.gtefsd.com!news.ans.net!newsgate.watson.ibm.com!yktnews.watson.ibm.com!ncohen @ 1993-07-26 15:12 UTC (permalink / raw)


In article <9307201257.AA00575@eight-ball.boeing.com>,
crispen@eight-ball.boeing.com (Bob Crispen) writes: 

|> Adam Beneschan queries the legality of the following: 
|>
|> >      type One_Byte is range 0..7;
|> >      type Four_Bytes is range 0..31;
|>
|> >      for Landing_Gear_Parameters use
|> >       record
|> >         Position   at 0 range Four_Bytes;
|> >         State      at 4 range One_Byte;
|> >       end record;
|>
|> and another correspondent who hasn't given me permission to quote
|> him says that his Alsys Ada compiler won't compile the code above,
|> while all 3 of my VADS compilers (of different vintages, and for
|> different targets) will.

As other correspondents have pointed out, the syntax rules in RM 13.4(2)
and 3.5(2) make it clear that this should be rejected, and AI-00498
forbids even

      0 range Four_Bytes'Range

on the grounds that 'Range is not a static attribute.  (This
attribute will be static in Ada 9X--see 4.9(25) of Ada 9X RM draft
3.0--but the syntax of a component clause is changed to

   component_clause_component_name at position range first_bit .. last_bit;

where first_bit and last_bit are static simple expressions, so the
component clause above will be forbidden in Ada 9Xfor a different
reason.)

|> What I had in mind of course was analogous to the universal practice: 
|>
|>      type Colors is (Mauve, Puce, Ultraviolet);
|>      for Each_Color in Colors loop
|>
|>
|> "in Colors" being shorthand for "in Colors'first..Colors'last".  I
|> believe every Ada compiler accepts this, but I can't find the
|> LRM entry that says where it has to.  Probably right under my nose.

The syntax of a loop parameter specification in a for loop (RM 5.5(2))
calls for a "discrete_range", which is different from a "range".  A
"discrete_range" can be either a "subtype_indication" or a "range"
(RM 3.6(2)) and a "subtype_indication" is a type mark (like Colors)
optionally followed by a constraint (RM 3.3.2(2)).

--
Norman H. Cohen    ncohen@watson.ibm.com

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

* Re: Forcing default representations
@ 1993-07-26 18:30 Robert I. Eachus
  0 siblings, 0 replies; 12+ messages in thread
From: Robert I. Eachus @ 1993-07-26 18:30 UTC (permalink / raw)


In article <9307201257.AA00575@eight-ball.boeing.com> crispen@eight-ball.boeing
.com (Bob Crispen) writes:

   > What I had in mind of course was analogous to the universal practice:

   >       type Colors is (Mauve, Puce, Ultraviolet);
   >	   for Each_Color in Colors loop

   > "in Colors" being shorthand for "in Colors'first..Colors'last".  I
   > believe every Ada compiler accepts this, but I can't find the
   > LRM entry that says where it has to.  Probably right under my nose.

In 3.6(2) of course:

   discrete_range ::= discrete_subtype_indication | range

since 13.4(2) says

   component_clause ::= 
      component_name at static_simple_expression range static_range;

   (The second occurances of discrete and component should be
italicized, as should both occurances of static.  The words "at" and the
the first "range" in component clause are reserved).

   > So, here's the question -- whose compiler has the bug in it?  Or have
   > I, in my quest to write portable code, ended up writing non-portable
   > code?  If you pick the latter, please say why!

     Any compiler that rejects your component clauses is correct.  The
DEC case is not quite as clear, but I don't read 13.4(8) as applying
here.  Report it as a bug if you want, however, I think that in no
case should DEC change this behavior if people depend on it.  (But
change your software to be portable, if your goal is portability. :-)



--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...

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

* Re: Forcing default representations
@ 1993-07-30  1:15 pipex!warwick!zaphod.crihan.fr!univ-lyon1.fr!scsing.switch.ch!epflnews!di
  0 siblings, 0 replies; 12+ messages in thread
From: pipex!warwick!zaphod.crihan.fr!univ-lyon1.fr!scsing.switch.ch!epflnews!di @ 1993-07-30  1:15 UTC (permalink / raw)


In article <9307131922.AA04017@eight-ball.boeing.com>, crispen@eight-ball.boein
g.com (crispen) writes:

|> So basically I'm going after having the best of all possible worlds:
|> we have rep specs (essential, because we're defining objects that are
|> going on a network between two machines of possibly different
|> architectures), but the person who is modifying this file should
|> be able to add or delete from the Aircraft_Trim enumeration at will,
|> and the rep specs are generated automatically.  Cool!

Writing representation specifications for all your types does not help in sendi
ng over a
network, because you still depend on whether your machine is big endian or litt
le
endian. Communicating values between machines with the same endianity will work
, but
will fail if one machine is big endian and the other is little endian.

Ada has no way of specifying exact layout of records: you will never know where
 the
most/least significant bit goes.

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

* Re: Forcing default representations
@ 1993-07-30 12:00 Bob Gilbert
  0 siblings, 0 replies; 12+ messages in thread
From: Bob Gilbert @ 1993-07-30 12:00 UTC (permalink / raw)


In article 030333@lglsun.epfl.ch, madmats@lglsun.epfl.ch (Mats Weber) writes:
>
>Ada has no way of specifying exact layout of records: you will never know wher
e the
>most/least significant bit goes.

Not true.  Ada does provide a way of specifying exact layout of records.  The
problem is that it is implementation dependent.  But you will know what it is
for the target you are working with.

                         Bob

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

end of thread, other threads:[~1993-07-30 12:00 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1993-07-26 15:12 Forcing default representations agate!howland.reston.ans.net!europa.eng.gtefsd.com!news.ans.net!newsgate.watson.ibm.com!yktnews.watson.ibm.com!ncohen
  -- strict thread matches above, loose matches on Subject: below --
1993-07-30 12:00 Bob Gilbert
1993-07-30  1:15 pipex!warwick!zaphod.crihan.fr!univ-lyon1.fr!scsing.switch.ch!epflnews!di
1993-07-26 18:30 Robert I. Eachus
1993-07-24 21:16 Erik Magnuson
1993-07-24 17:13 pipex!sunic!news.funet.fi!funic!news.eunet.fi!prime!mits!rkaivola
1993-07-23 19:15 Gary Morris @ignite
1993-07-22 18:34 Bob Crispen
1993-07-20 12:57 Bob Crispen
1993-07-19 16:56 Adam Beneschan
1993-07-16 22:26 dog.ee.lbl.gov!overload.lbl.gov!agate!howland.reston.ans.net!noc.near.net
1993-07-13 19:22 crispen

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