I’m writing an SDL/input library for my game in Free Pascal, and I’m facing an issue.
I’ve got a variant record that, when I access an element of it, changes the other elements.
The record type is:
tInput = Record
case Device: TInputDevice of
ID_KeyOnce, ID_KeyCont: (Key: TSDLKey);
ID_MouseButton: (MouseButton: Byte);
ID_MouseAxis, ID_JoyAxis,
ID_JoyBall, ID_JoyHat: (Axis: Byte);
ID_JoyButton, ID_JoyButtonOnce, ID_JoyAxis,
ID_JoyHat, ID_JoyBall: (Which: Byte);
ID_JoyButton, ID_JoyButtonOnce: (Button: Byte);
end;
The code that crashes it is:
with Input do begin
Device := ID_JoyAxis;
Which := 0;
Axis := 1;
end;
When axis is set to one, all of the other variables in the record go to one two!
Is this a known bug? Or some functionality I’m not aware of? Or something I’ve screwed up?
This is called a union and intended behavior of this type of record declaration.
… is the “magic” here.
In a union the storage of members is “shared”.
Edit: taking the record you have in terms of byte offsets (… under the assumption that
sizeof(TSDLKey) = 4):By the rules I know, TInputDevice should be an enum type, otherwise you’d have to explicitly give
Integerthere:NB: it is customary for variant types to have one member describe which of the union members should be picked and valid (nested unions).