记录字段覆盖其他字段

时间:2011-03-02 03:36:04

标签: freepascal

我正在SDL为我的游戏编写Free Pascal /输入库,我正面临一个问题。

我有一个变体记录,当我访问它的一个元素时,会更改其他元素。

记录类型为:

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);

端;

崩溃的代码是:

with Input do begin
    Device := ID_JoyAxis;
    Which  := 0;
    Axis   := 1;
end;

当axis设置为1时,记录中的所有其他变量都会变为一个!

这是一个已知的错误吗?或者我不知道的一些功能?或者我搞砸了什么?

1 个答案:

答案 0 :(得分:1)

这称为此类记录声明的联合和预期行为。

case Device : TInputDevice of

......这里是“神奇”。

在联盟中,成员的存储是“共享的”。

编辑:根据字节偏移(...假设sizeof(TSDLKey) = 4)获取记录:

------------------------------------------------
00 | Key | MouseButton | Axis | Which | Button |
---|     |-------------|------|-------|--------|
01 |     |             |      |       |        |
---|     |-------------|------|-------|--------|
02 |     |             |      |       |        |
---|     |-------------|------|-------|--------|
03 |     |             |      |       |        |
------------------------------------------------

根据我所知的规则,TInputDevice应该是一个枚举类型,否则你必须在那里明确地给出Integer

type xyz = record
  case integer of
  0: (foo: Byte);
  1: (bar: Integer);
end;

NB:变体类型习惯上有一个成员描述应该选择哪个联合成员并且有效(嵌套联合)。