comp.lang.ada
 help / color / mirror / Atom feed
* Variant record assignment fails discriminant check
@ 2009-09-02 14:25 vldmr
  2009-09-02 14:52 ` Adam Beneschan
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: vldmr @ 2009-09-02 14:25 UTC (permalink / raw)


For the folllowing variant record:
------------------------------------------
type t_X520CommonName_Choice_Id is (
        X520CommonName_teletexString,
        X520CommonName_printableString
-- more choices
    );
type t_X520CommonName (choice_Id : t_X520CommonName_Choice_Id :=
X520CommonName_teletexString) is record -- CHOICE
    case choice_Id is
        when X520CommonName_teletexString =>
            teletexString : t_TeletexString_Acc; -- TeletexString
(SIZE (1..ub-common-name))
        when X520CommonName_printableString =>
            printableString : t_PrintableString_Acc; --
PrintableString (SIZE (1..ub-common-name))
-- ... more choices
     end case;
end record;
----------------------------------
the following code:
---------------------------------
    procedure BDec_X520CommonNameContent(tagId0 : t_Asn_Tag;v: out
t_X520CommonName;) is
    begin
        case tagId0 is
            when
                16#14000000# | -- UNIV PRIM TELETEXSTRING_TAG_CODE
                16#34000000#   -- UNIV CONS TELETEXSTRING_TAG_CODE
                =>
                declare
                    teletexString : t_TeletexString_Acc;
                begin
                    teletexString := Adr_2_t_TeletexString_Acc
( Asn1_Alloc ( t_TeletexString'Size / 8));
                    Check_Asn1_Alloc (teletexString.all'Address,
exceptProc);
                    BDec_TeletexStringContent (tagId0, elmtLen0,
teletexString.all, totalElmtsLen1, exceptProc);
                    v := (choice_Id => X520CommonName_teletexString,
teletexString => teletexString); -- CONSTRAINT_ERROR
                end;
	-- ... more choices
       end case;
    end BDec_X520CommonNameContent;
--------------------------------------
when executed produces 'discriminant check failed' error on assignment
to v.

Why is that? As far as I understand the variable v shall be mutable.
Any hint is greatly appreciated

Thanks,
Vladimir



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

* Re: Variant record assignment fails discriminant check
  2009-09-02 14:25 Variant record assignment fails discriminant check vldmr
@ 2009-09-02 14:52 ` Adam Beneschan
  2009-09-02 15:09   ` vldmr
  2014-05-12  0:31 ` maniyazhagan
  2014-05-12  0:32 ` maniyazhagan
  2 siblings, 1 reply; 7+ messages in thread
From: Adam Beneschan @ 2009-09-02 14:52 UTC (permalink / raw)


On Sep 2, 7:25 am, vldmr <vldm...@gmail.com> wrote:
> For the folllowing variant record:
> ------------------------------------------
> type t_X520CommonName_Choice_Id is (
>         X520CommonName_teletexString,
>         X520CommonName_printableString
> -- more choices
>     );
> type t_X520CommonName (choice_Id : t_X520CommonName_Choice_Id :=
> X520CommonName_teletexString) is record -- CHOICE
>     case choice_Id is
>         when X520CommonName_teletexString =>
>             teletexString : t_TeletexString_Acc; -- TeletexString
> (SIZE (1..ub-common-name))
>         when X520CommonName_printableString =>
>             printableString : t_PrintableString_Acc; --
> PrintableString (SIZE (1..ub-common-name))
> -- ... more choices
>      end case;
> end record;
> ----------------------------------
> the following code:
> ---------------------------------
>     procedure BDec_X520CommonNameContent(tagId0 : t_Asn_Tag;v: out
> t_X520CommonName;) is
>     begin
>         case tagId0 is
>             when
>                 16#14000000# | -- UNIV PRIM TELETEXSTRING_TAG_CODE
>                 16#34000000#   -- UNIV CONS TELETEXSTRING_TAG_CODE
>                 =>
>                 declare
>                     teletexString : t_TeletexString_Acc;
>                 begin
>                     teletexString := Adr_2_t_TeletexString_Acc
> ( Asn1_Alloc ( t_TeletexString'Size / 8));
>                     Check_Asn1_Alloc (teletexString.all'Address,
> exceptProc);
>                     BDec_TeletexStringContent (tagId0, elmtLen0,
> teletexString.all, totalElmtsLen1, exceptProc);
>                     v := (choice_Id => X520CommonName_teletexString,
> teletexString => teletexString); -- CONSTRAINT_ERROR
>                 end;
>         -- ... more choices
>        end case;
>     end BDec_X520CommonNameContent;
> --------------------------------------
> when executed produces 'discriminant check failed' error on assignment
> to v.
>
> Why is that? As far as I understand the variable v shall be mutable.

Only if the actual parameter is mutable when you call the procedure.

Say you declare

   XYZ : t_X520CommonName (X520CommonName_printableString);

...
   BDec_X520CommonNameContent (Something, XYZ);

XYZ is a constrained record.  You wouldn't want
BDec_X520CommonNameContent violating the constranit of XYZ by changing
the discriminant, would you?

On the other hand, if you declare

   ZYX : t_X520CommonName;
...
   BDec_X520CommonNameContent (Something, ZYX);

ZYX is unconstrained, so it's OK for BDec_X520CommonNameContent to
change the discriminant.  This means that the compiler has to generate
a little extra code to pass something to the procedure to tell it
whether it's OK to change the discriminant.

OK, so I'll bet your next question is: So how do I declare an object
to be unconstrained (mutable), but give its discriminant an initial
value other than the default (X520CommonName_teletexString)?

   WXY : t_X520CommonName := (choice_Id =>
X520CommonName_printableString,
                              others => <>);

                                          -- Adam



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

* Re: Variant record assignment fails discriminant check
  2009-09-02 14:52 ` Adam Beneschan
@ 2009-09-02 15:09   ` vldmr
  2009-09-02 15:33     ` Adam Beneschan
  0 siblings, 1 reply; 7+ messages in thread
From: vldmr @ 2009-09-02 15:09 UTC (permalink / raw)


On Sep 2, 9:52 am, Adam Beneschan <a...@irvine.com> wrote:
> On Sep 2, 7:25 am, vldmr <vldm...@gmail.com> wrote:
>
> Only if the actual parameter is mutable when you call the procedure.
...
>
> OK, so I'll bet your next question is: So how do I declare an object
> to be unconstrained (mutable), but give its discriminant an initial
> value other than the default (X520CommonName_teletexString)?
>
>    WXY : t_X520CommonName := (choice_Id =>
> X520CommonName_printableString,
>                               others => <>);
>
>                                           -- Adam

Oh, thank, make sense now. At least I see where my problem is. In my
case WXY is actually declared as access to record, and is initialized
using Unchecked_Conversion from external memory address, pointing to
zero filled memory.

Any advice how to declare an access to variant record to be mutable?

Thank you,

Vladimir



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

* Re: Variant record assignment fails discriminant check
  2009-09-02 15:09   ` vldmr
@ 2009-09-02 15:33     ` Adam Beneschan
  2009-09-02 16:09       ` vldmr
  0 siblings, 1 reply; 7+ messages in thread
From: Adam Beneschan @ 2009-09-02 15:33 UTC (permalink / raw)


On Sep 2, 8:09 am, vldmr <vldm...@gmail.com> wrote:
> On Sep 2, 9:52 am, Adam Beneschan <a...@irvine.com> wrote:
>
> > On Sep 2, 7:25 am, vldmr <vldm...@gmail.com> wrote:
>
> > Only if the actual parameter is mutable when you call the procedure.
> ...
>
> > OK, so I'll bet your next question is: So how do I declare an object
> > to be unconstrained (mutable), but give its discriminant an initial
> > value other than the default (X520CommonName_teletexString)?
>
> >    WXY : t_X520CommonName := (choice_Id =>
> > X520CommonName_printableString,
> >                               others => <>);
>
> >                                           -- Adam
>
> Oh, thank, make sense now. At least I see where my problem is. In my
> case WXY is actually declared as access to record, and is initialized
> using Unchecked_Conversion from external memory address, pointing to
> zero filled memory.
>
> Any advice how to declare an access to variant record to be mutable?

I don't think the language will let you do this, directly.  If you
declare a type "type acc_t_X520CommonName is access all
t_X520CommonName", and an object Acc of this access type, then Acc.all
is assumed to be constrained, and if you pass Acc.all to your
procedure, the procedure can't change it.  (The original motivation
was, I think, that you can declare a constrained subtype of the access
type; if you have an access object of that constrained subtype and
make it point to an object with the correct discriminant, it would be
bad if the language let you change the discriminant via a different,
unconstrained, access object.  There have been some language changes
regarding discriminants on access types, and I'm not familiar with all
of them, so maybe you can do things you previously couldn't.  I'm not
sure.)

However, you can get around this by embedding the variant record
inside another record:

   type Rec is record
      Name : t_X520CommonName;
   end record;
   type Acc_Rec is access all Rec;

Now, if X has type Acc_Rec, you can pass X.Name to your procedure, and
it will be unconstrained (and therefore mutable).

This is a workaround that I've used extensively in my own code, by the
way.

                                      -- Adam




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

* Re: Variant record assignment fails discriminant check
  2009-09-02 15:33     ` Adam Beneschan
@ 2009-09-02 16:09       ` vldmr
  0 siblings, 0 replies; 7+ messages in thread
From: vldmr @ 2009-09-02 16:09 UTC (permalink / raw)


On Sep 2, 10:33 am, Adam Beneschan <a...@irvine.com> wrote:

> However, you can get around this by embedding the variant record
> inside another record:
>
>    type Rec is record
>       Name : t_X520CommonName;
>    end record;
>    type Acc_Rec is access all Rec;
>
> Now, if X has type Acc_Rec, you can pass X.Name to your procedure, and
> it will be unconstrained (and therefore mutable).
>
> This is a workaround that I've used extensively in my own code, by the
> way.
>
>                                       -- Adam

Yup, that works. I can not say I quite understand why, so for sure I
would not be able to invent that by myself.

Thank you very much!

Vladimir



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

* Re: Variant record assignment fails discriminant check
  2009-09-02 14:25 Variant record assignment fails discriminant check vldmr
  2009-09-02 14:52 ` Adam Beneschan
@ 2014-05-12  0:31 ` maniyazhagan
  2014-05-12  0:32 ` maniyazhagan
  2 siblings, 0 replies; 7+ messages in thread
From: maniyazhagan @ 2014-05-12  0:31 UTC (permalink / raw)


Hi

please let me know,
what will be the output of v.

by
Mani


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

* Re: Variant record assignment fails discriminant check
  2009-09-02 14:25 Variant record assignment fails discriminant check vldmr
  2009-09-02 14:52 ` Adam Beneschan
  2014-05-12  0:31 ` maniyazhagan
@ 2014-05-12  0:32 ` maniyazhagan
  2 siblings, 0 replies; 7+ messages in thread
From: maniyazhagan @ 2014-05-12  0:32 UTC (permalink / raw)


Hi Vladimir,

what will be the output of V.

Thanks,

Regards,
Maniyazhagan S


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

end of thread, other threads:[~2014-05-12  0:32 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-02 14:25 Variant record assignment fails discriminant check vldmr
2009-09-02 14:52 ` Adam Beneschan
2009-09-02 15:09   ` vldmr
2009-09-02 15:33     ` Adam Beneschan
2009-09-02 16:09       ` vldmr
2014-05-12  0:31 ` maniyazhagan
2014-05-12  0:32 ` maniyazhagan

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