【问题标题】:Structures containing conditional fields in CC 中包含条件字段的结构
【发布时间】:2016-05-08 12:26:03
【问题描述】:

我正在尝试实现一个协议标准,但我在他们的条件字段概念上遇到了一些麻烦。它们被定义为根据某些条件存在或不存在的字段。他们给出的例子如下:

    uint16 Pressure;
    enum VehicleType { car = 0, motorbike = 1};
    struct TirePressureInfo {
                    VehicleType type;
                    select (type)
                    {
                    case car:
                            Pressure frontLeft;
                            Pressure frontRight;
                            Pressure rearLeft;
                            Pressure rearRight;
                    case motorbike:
                            Pressure front;
                            Pressure rear;
                    }
            }

无论如何,我都不知道在 C 中进行这项工作,或者是否有可能。无论如何,我想不出实现这一点。需要注意的一点是,这将在 Linux 内核模块中实现,所以我也受到了一些限制。

            struct {
                    uint8 protocol_version;
                    ContentType type;
                    select (type) {
                    case unsecured :
                    opaque data<var>;
                    case signed, signed_partial_payload,
                    signed_external_payload:
                    SignedData signed_data;
                    case signed_wsa:
                    SignedWsa signed_wsa;
                    case encrypted :
                    EncryptedData encrypted_data;
                    case crl_request :
                    CrlRequest crl_request;
                    case crl :
                    Crl crl;
                    case other_value:
                    opaque data<var>;
                    }
            } 1609Dot2Data;




    struct {
            SignerIdentifierType type;
            select (type) {
            case self: ;
            case certificate_digest_with_ecdsap224 :
            case certificate_digest_with_ecdsap256 :
                    HashedId8 digest;
                    opaque data<var>;
            case certificate:
                    Certificate certificate;
            case certificate_chain:
                    Certificate certificates<var>;
            case certificate_digest_with_other_algorithm :
                    Signer signer;
                    PKAlgorithm algorithm;
                    HashedId8 digest;
            case other_value:
                    opaque id<var>;
            }
    } SignerIdentifier;

【问题讨论】:

  • 我认为您正在寻找union
  • 联合或包含所有可能字段的超级结构。 C 中没有条件字段之类的东西。
  • 联合只是以不同的方式表示数据,对吧?我需要结构中包含不同的字段,而不仅仅是表示它们的不同方式。
  • 如果你拒绝使用union,你的问题就不清楚了。同时使用不同的字段意味着您需要struct
  • 非常值得看一下 Neil Brown 在 LWN 上的内核设计模式文章,例如)lwn.net/Articles/446317 讨论了文件系统的数据结构,这些文件系统像摩托车和汽车可能有共同的部分和专门的部分。拥有嵌入车辆结构的汽车可能比拥有汽车/自行车联合的车辆更好。

标签: c struct linux-kernel conditional


【解决方案1】:

您可以使用union

uint16 Pressure;
enum VehicleType { CAR = 0, MOTORBIKE = 1};
struct TirePressureInfo {
  VehicleType type;
  union {
    struct {
      Pressure frontLeft;
      Pressure frontRight;
      Pressure rearLeft;
      Pressure rearRight;
    } car;
    struct {
      Pressure front;
      Pressure rear;
    } motorbike;
  } data;
};

那么你可以这样设置:

struct TirePressureInfo info;
info.type = CAR;
info.data.car.frontLeft  = 35;
info.data.car.frontRight = 35;
info.data.car.rearLeft   = 32;
info.data.car.rearRight  = 32;

或者如果你想定义一个MOTORBIKE:

struct TirePressureInfo info;
info.type = MOTORBIKE;
info.data.motorbike.front = 38;
info.data.motorbike.rear  = 40;

当你阅读它时,你应该检查type

switch ( info.type ) {
case CAR:
    /* read info.data.car fields */
    break;
case MOTORBIKE:
    /* read info.data.motorbike fields */
    break;
default:
    /* Some data integrity problem */
}

如果您确定一次只需要一个struct carstruct motorbike(取决于type 的值),那么就没有必要让每个TirePressureInfo 都包含both struct car 的字段和 struct motorbike 的字段。使用union 会使struct carstruct motorbike 在内存中占据相同的位置。 union 的实际大小是greater of the two。这只是为您提供了不同的方式来读取和写入内存中的同一位置。

【讨论】:

  • 这对我来说更有意义。尝试将其可视化有点困难,因为我对工会的经验很少。
猜你喜欢
  • 2014-05-08
  • 1970-01-01
  • 2013-07-12
  • 2012-08-08
  • 1970-01-01
  • 1970-01-01
  • 2014-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多