Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!orion.oac.uci.edu!ucivax!milne From: milne@ics.uci.edu (Alastair Milne) Newsgroups: comp.lang.pascal Subject: Re: need a little flexibility Message-ID: <2818F692.27076@ics.uci.edu> Date: 27 Apr 91 03:57:05 GMT References: <1991Apr24.183315.7997@ux1.cso.uiuc.edu> <1991Apr24.235739.25115@watmath.waterloo.edu> <91115.111155IO92203@MAINE.BITNET> Distribution: na Organization: UC Irvine Department of ICS Lines: 79 In <91115.111155IO92203@MAINE.BITNET> IO92203@MAINE.BITNET (Scott Maxell) writes: >In article <1991Apr24.235739.25115@watmath.waterloo.edu>, >> x : byte; >> y : byte; >> case boolean of >> True : (data : array[1..252] of byte); >> False: (dataw: array[1..126] of word); >>end; >> .... >> b.data[i] := hi(w); >> b.dataw[i] := w; >>end. >> > This last approach won't work as stated because a variant record can >only contain one of the possible fields declared. The field in the variant >should also have a declared variable and not just a type. Not true!! Pascal does *not* guard against using whichever of the variants you want at any time. Ada has constructions which do, but Pascal does not. Nor does the tagfield actually have to be an allocated field, rather than just a type. It *can* be, of course, if you want your program to be able to ask as which variant a give instance of the record was created, but there's no obligation. >Type > Block = RECORD > X, > Y : Byte; > Case WordData : Boolean OF > True : ( DataW : ARRAY [1..126] OF Word ); > False : ( Data : ARRAY [1..252] OF Byte ); > END; (* record *) >VAR > WordData : BOOLEAN; > OneWord : Word; > OneByte : Byte; >BEGIN > B.WordData := True; (* or false depending on what your data is. *) > OneByte := ????; (* Your byte data. *) > OneWord := ????; (* Your word data. *) > n := ????; (* Array index. *) > Case B.WordData OF > True : B.Data [n] := OneByte; > False : B.DataW [n] := OneWord; { All this is internally consistent, but you could as easily write FALSE: B.Data[N] := OneByte; and Pascal wouldn't care at all. } > END; (* case *) >END; > When adding data to a variant record, there needs to be a value placed in >the tag field, or you will generally get an error. You will get errors if the program is counting on telling by the tag field which variant is being used, since not being able to tell may cause it to assign to the wrong variant, possibly with the wrong size, overwrite memory, etc. etc. . Then an uninitialised tag field will wreak havoc -- but not because of any internal bindings, simply because it's supplying the assignment algorithm with false information. But this is typically in the case of dynamically allocated variant records, not the static ones given here. But if your routines are not themselves making use of the tag field, there is no need to have one. Note I am speaking of UCSD Pascal and Turbo Pascal. I don't have the ANSI standards available -- they may be more rigid. Alastair Milne