包含C中条件字段的结构

See*_*hay 1 c conditional struct linux-kernel

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

    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;
                    }
            }
Run Code Online (Sandbox Code Playgroud)

无论如何我都没有意识到要在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;
Run Code Online (Sandbox Code Playgroud)

e0k*_*e0k 6

你可以使用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;
};
Run Code Online (Sandbox Code Playgroud)

那么你可以设置它:

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;
Run Code Online (Sandbox Code Playgroud)

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

struct TirePressureInfo info;
info.type = MOTORBIKE;
info.data.motorbike.front = 38;
info.data.motorbike.rear  = 40;
Run Code Online (Sandbox Code Playgroud)

当你读它时,你应该检查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 */
}
Run Code Online (Sandbox Code Playgroud)

如果你确定你只需要一次struct carstruct motorbike一次(取决于其价值type),那么就不需要通过TirePressureInfo包含两个 struct car字段和struct motorbike字段来浪费空间.使用a union使得struct carstruct motorbike占据内存中的相同位置.实际大小union是两者中较大的一个.这只是为您提供了不同的方式来读取和写入内存中的相同位置.