C宏/函数返回多种类型

C宏/函数返回多种类型,c,macros,C,Macros,我有一个名为tfm的通用对象,它可以是3种更大的类型(tfm是其他3种结构的开始)。基于tfm中的字段,我可以确定tfm属于哪个更大的结构。 所有3种结构类型都有一个以相同方式命名的字段(reqsize),但该字段不在tfm中。 是否有一些宏魔术可以让我做这样的事情: CAST_UPPER(tfm)->reqsize ? 它可以是特定于gcc编译器扩展的。与任何具有结果的表达式(例如 )将无法编译,因为各种结果表达式具有不同的类型。你必须有这样的东西 #define CAST_UPPER

我有一个名为tfm的通用对象,它可以是3种更大的类型(tfm是其他3种结构的开始)。基于tfm中的字段,我可以确定tfm属于哪个更大的结构。
所有3种结构类型都有一个以相同方式命名的字段(reqsize),但该字段不在tfm中。
是否有一些宏魔术可以让我做这样的事情:

CAST_UPPER(tfm)->reqsize


它可以是特定于gcc编译器扩展的。

与任何具有结果的表达式(例如

)将无法编译,因为各种结果表达式具有不同的类型。你必须有这样的东西

#define CAST_UPPER(tfm, field) \
    (tfm)->type == TYPE1 ? (type1*)(tfm)->field : \
    (tfm)->type == TYPE2 ? (type2*)(tfm)->field : 
                           (type3*)(tfm)->field
我认为这是一个相当脆弱的设计,您最好在
tfm
中使用
reqsize
,或者至少其他3个
struct
包含一个公共
struct
,其中包含
tfm
reqsize
,因此

typedef struct TFM { ... } TFM;
typedef struct TFMREQ {
     TFM tfm;
     size_t reqsize;
} TFMREQ;
struct TYPE1 { TFMREQ tfmreq; ... };
struct TYPE2 { TFMREQ tfmreq; ... };
struct TYPE3 { TFMREQ tfmreq; ... };

然后您可以只做
(TFMREQ*)tfm->reqsize

而不是像任何有结果的表达式(例如

)将无法编译,因为各种结果表达式具有不同的类型。你必须有这样的东西

#define CAST_UPPER(tfm, field) \
    (tfm)->type == TYPE1 ? (type1*)(tfm)->field : \
    (tfm)->type == TYPE2 ? (type2*)(tfm)->field : 
                           (type3*)(tfm)->field
我认为这是一个相当脆弱的设计,您最好在
tfm
中使用
reqsize
,或者至少其他3个
struct
包含一个公共
struct
,其中包含
tfm
reqsize
,因此

typedef struct TFM { ... } TFM;
typedef struct TFMREQ {
     TFM tfm;
     size_t reqsize;
} TFMREQ;
struct TYPE1 { TFMREQ tfmreq; ... };
struct TYPE2 { TFMREQ tfmreq; ... };
struct TYPE3 { TFMREQ tfmreq; ... };

然后您可以只做
(TFMREQ*)tfm->reqsize

而不是像任何有结果的表达式(例如

)将无法编译,因为各种结果表达式具有不同的类型。你必须有这样的东西

#define CAST_UPPER(tfm, field) \
    (tfm)->type == TYPE1 ? (type1*)(tfm)->field : \
    (tfm)->type == TYPE2 ? (type2*)(tfm)->field : 
                           (type3*)(tfm)->field
我认为这是一个相当脆弱的设计,您最好在
tfm
中使用
reqsize
,或者至少其他3个
struct
包含一个公共
struct
,其中包含
tfm
reqsize
,因此

typedef struct TFM { ... } TFM;
typedef struct TFMREQ {
     TFM tfm;
     size_t reqsize;
} TFMREQ;
struct TYPE1 { TFMREQ tfmreq; ... };
struct TYPE2 { TFMREQ tfmreq; ... };
struct TYPE3 { TFMREQ tfmreq; ... };

然后您可以只做
(TFMREQ*)tfm->reqsize

而不是像任何有结果的表达式(例如

)将无法编译,因为各种结果表达式具有不同的类型。你必须有这样的东西

#define CAST_UPPER(tfm, field) \
    (tfm)->type == TYPE1 ? (type1*)(tfm)->field : \
    (tfm)->type == TYPE2 ? (type2*)(tfm)->field : 
                           (type3*)(tfm)->field
我认为这是一个相当脆弱的设计,您最好在
tfm
中使用
reqsize
,或者至少其他3个
struct
包含一个公共
struct
,其中包含
tfm
reqsize
,因此

typedef struct TFM { ... } TFM;
typedef struct TFMREQ {
     TFM tfm;
     size_t reqsize;
} TFMREQ;
struct TYPE1 { TFMREQ tfmreq; ... };
struct TYPE2 { TFMREQ tfmreq; ... };
struct TYPE3 { TFMREQ tfmreq; ... };

然后,您可以只执行
(TFMREQ*)tfm->reqsize

使用枚举类型、内联函数和疯狂优化编译器,预处理器最好包括头和条件编译。它的“缺点”有很好的文档记录,应该尽可能避免。使用枚举类型、内联函数和疯狂优化的编译器,预处理器最好包括头和条件编译。它的“缺点”有很好的文档记录,应该尽可能避免。使用枚举类型、内联函数和疯狂优化的编译器,预处理器最好包括头和条件编译。它的“缺点”有很好的文档记录,应该尽可能避免。使用枚举类型、内联函数和疯狂优化的编译器,预处理器最好包括头和条件编译。它的“缺点”有很好的记录,应该尽可能避免。