Usage of pascal variant record

I need help from those who know the pascal very well. I need (teachers requirement) to use a variant record. Those variant record are defined like this:

Temperature = record case scale : TemperatureScale of celsius : (celsius_value : ScaleCelsius); kelvin : (kelvin_value : ScaleKelvin); end; 

According to primary sources I found during my research about this topic, I could not find how to use variant record, only how to declare it. My primary sources: google search(found nothing), Case-Freepascal and Record-Freepascal Edit for those who wonder what i must use in implementation it is exacly this:

 type UkPolozka = ^Polozka; UkHodnota = ^Hodnota; TypUdaj=(typretez, typcele, typrealne, typlogik, typpole, typobjekt); VarZaznam = record case Udaj: TypUdaj of typretez: (retez: string); typcele: (cele: word); typrealne: (realne: single); typlogik: (logik: boolean); typpole: (pole: UkHodnota); typobjekt: (objekt: UkPolozka); end; Polozka = record Nazev: string; Hodn: VarZaznam; Dalsi: UkPolozka end; Hodnota = record Hodn: VarZaznam; Dalsi: UkHodnota end; 
21k 8 8 gold badges 41 41 silver badges 57 57 bronze badges asked Dec 7, 2017 at 9:19 13 1 1 silver badge 5 5 bronze badges

You have not described specific problem. Consider freepascal.org/docs-html/rtl/sysutils/longrec.html as example of useful variant record

Commented Dec 7, 2017 at 9:34

If record field scale is celsius , the variant part contains the celsius_value . If it is kelvin , then the variant part contains the kelvin_value . The variant part shares room for multiple interpretations depending on the variant descriptor. The variant descriptor can also be specified as a type only. case boolean of .

Commented Dec 7, 2017 at 10:03 @mbo how figure type of record? and how read from it? Commented Dec 7, 2017 at 13:43 Surely this is all covered in your lessons and your text books. Commented Dec 7, 2017 at 16:09 @DavidHeffernan nope. it is not. teacher breafly mentioned it during class 3 or more weeks ago . Commented Dec 7, 2017 at 20:39

1 Answer 1

Consider example record from Delphi Help. I modified it with tag.

Tag usage is optional and usually is not used and doesn't provide useful information.
Note that the first line outputs radius with the same value as height - they share the same memory.

Then I explicitly set tag (but fields stay the same)

Also note size difference for no-tag record and tagged one.

Note again - in most cases programmers don't define or use tag value. It might be unsafe to rely on tag (until you follow strict rules in assigning tags). I did not set rectangle tag, but program consider zero tag as the first variant.

Just assign needed field by name. Just read needed field by name. For your example varVarZaznam.retez:= 'test';

type TShapeList = (Rectangle, Triangle, Circle, Ellipse, Other); TFigure = record case shape: TShapeList of Rectangle: (Height, Width: Real); Triangle: (Side1, Side2, Angle: Real); Circle: (Radius: Real); Ellipse, Other: (); end; TFigureNoTag = record case TShapeList of Rectangle: (Height, Width: Real); Triangle: (Side1, Side2, Angle: Real); Circle: (Radius: Real); Ellipse, Other: (); end; var Fig: TFigure; begin Fig.Height := 5; Fig.Width := 3; //default tag is zero = Rectangle if Fig.shape = Rectangle then Writeln('Rect ', Fig.Height:3:0, Fig.Width:3:0, Fig.Radius:3:0) else Writeln('not Rect'); Fig.shape := Circle; if Fig.shape <> Rectangle then Writeln('not Rect'); Writeln('Fig size ', SizeOf(TFigure), ' noTag size ', SizeOf(TFigureNoTag)); Readln; 

output in Delphi:

Rect 5 3 5 not Rect Fig size 32 noTag size 24