From: vldmr on 2 Sep 2009 10:25 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
From: Adam Beneschan on 2 Sep 2009 10:52 On Sep 2, 7:25 am, vldmr <vldm...(a)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
From: vldmr on 2 Sep 2009 11:09 On Sep 2, 9:52 am, Adam Beneschan <a...(a)irvine.com> wrote: > On Sep 2, 7:25 am, vldmr <vldm...(a)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
From: Adam Beneschan on 2 Sep 2009 11:33 On Sep 2, 8:09 am, vldmr <vldm...(a)gmail.com> wrote: > On Sep 2, 9:52 am, Adam Beneschan <a...(a)irvine.com> wrote: > > > On Sep 2, 7:25 am, vldmr <vldm...(a)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
From: vldmr on 2 Sep 2009 12:09 On Sep 2, 10:33 am, Adam Beneschan <a...(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
|
Pages: 1 Prev: Ada Shootout program for K-Nucleotide (patches) Next: AIDE by Stéphane Rivière |