comp.lang.ada
 help / color / mirror / Atom feed
From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: Variant Record Component
Date: Fri, 28 Feb 2003 14:51:43 -0600
Date: 2003-02-28T14:51:43-06:00	[thread overview]
Message-ID: <v5vir25vsj1e73@corp.supernews.com> (raw)
In-Reply-To: 3E5F8B38.EE7AE76F@boeing.com

John Harbaugh wrote in message <3E5F8B38.EE7AE76F@boeing.com>...
>Here's the situation:  I'm using a variant record to represent a Link
16
>(JTIDS) J7.6 message for memory-mapped I/O.  So a message comes in and,
>based on the message header, a particular structure is frozen.  Now I
>pass the message object to a decode function that is looking for
>particular message fields.  Well, surprise surprise, we occasionally
>raise Constraint_Error because the field in question is not present.
>
>Several options come to mind (in order of preferance):
>* Refactor the function and pass only the variant part instead of the
>entire message
>
>* Pass the discriminant value in to the function and have the function
>check it before referencing the variant part

I'm confused. How can you pass the message object to a function without
passing the discriminant? You can't pass part of a record in Ada, and if
you're passing the whole record, you're also passing the discriminant.
After all, if the generated code for the function is checking the value
of the discriminant, it must be available inside the function.

So, just test the discriminant inside the function. You're correct that
there is no convinient syntax for doing so (which is why tagged
extension records are a better choice than a variant for many uses), but
certainly it can be written. If you can arrange the variants to use
subtypes for their selectors, you can use memberships to make this more
maintainable. This would look something like:

    type Code_Type is range 0 .. 100;
    subtype Error_Codes is Code_Type range 90..100;
    subtype Result_Codes is Code_Type range 1 .. 10;
    subtype OK_Code is Code_Type range 0 .. 0;
    ...

    type Message_Type (Code : Code_Type) is record
          Header : ....;
          case Code is
              when OK_Code => null;
              when Result_Codes => Result : Integer;
              when Error_Codes => Error_Message : String(1..40);
             ...
          end case;
    end record;

    function Text_Message_Decode (Message : in Message_Type) return
String is
    begin
         case Message.Code is
             when OK_Code =>
               return "OK";
             when Error_Codes =>
               return Message.Error_Message;
             when Result_Codes =>
               return "Result=" & Integer'Image(Message.Result);
          ...
          end case;
     end Text_Message_Decode;

By using subtypes in this way, you won't have to change any of the uses
when the codes are changed (unless you add a variant). And if you add a
variant, the Ada completeness checking will insure that it's added to
all of the cases. Just avoid the temptation to use an others clause. We
use this extensively in the intermediate code for Janus/Ada, and the
checking has prevented a great many bugs.

            Randy.







  parent reply	other threads:[~2003-02-28 20:51 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-02-26 18:00 Variant Record Component John Harbaugh
2003-02-26 19:08 ` Stephen Leake
2003-02-27  8:17   ` Anders Wirzenius
2003-02-27  8:46     ` John McCabe
2003-02-27 17:26     ` phone number database Stephen Leake
2003-02-27 18:09       ` tmoran
2003-02-28  0:07       ` Matthew Heaney
2003-02-28  6:46       ` Hijacking threads (was phone number database (was Variant Record Component)) Anders Wirzenius
2003-02-26 20:50 ` Variant Record Component David C. Hoos
2003-02-28 16:15   ` John Harbaugh
2003-02-28 18:18     ` tmoran
2003-02-28 22:07       ` John Harbaugh
2003-02-28 20:51     ` Randy Brukardt [this message]
2003-03-01  2:34     ` Jeffrey Carter
2003-03-03  9:24     ` John McCabe
2003-02-26 21:37 ` tmoran
  -- strict thread matches above, loose matches on Subject: below --
2003-02-28 19:40 David C. Hoos
replies disabled

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