【问题标题】:Defining structure with elements present conditionally定义有条件存在的元素的结构
【发布时间】:2014-10-30 07:10:41
【问题描述】:

我正在尝试定义一个元素有条件存在的 C 结构。这是我要定义的标头的具体示例:

typedef struct flowHeader { 
    int magicNum ;
    int trafficType ;
    // few other int parameters
    int flowDirection; // Present ONLY if trafficType = TT_V6
    // few other int parameters 
} t_flowHeader ;

我想知道定义这种数据类型的最佳方式是什么。我想将此标头应用于在线接收的缓冲区。由于缺少一个元素 - 结构的大小变化 4 个字节,我正在努力如何管理它?

# define TT_V6 31
# define FD_NA 0
int flowDir ;
unsigned char buf[ MAXSZ ] ;
t_flowHeader * hdr ; 


hdr = (t_flowHeader *) buf ; 
if (hdr->trafficType == TT_V6) {
    flowDir = hdr->flowDirection ; 
} else {
    flowDir = FD_NA ; 
}

..

【问题讨论】:

  • 解除引用前重新排列buf中的4字节
  • 这不是一个选项 - 在某些时候我需要序列化这个结构的逻辑......所以改变顺序不是一个选择。这也将完全改变我通过将标题投射到传入消息缓冲区而获得的速度优势。

标签: c struct unions


【解决方案1】:

一种方法是使用两种不同的类型。您可以通过为所有其他共享组件定义嵌套类型来减少重复:

struct flowHeader_start { 
    int magicNum ;
    int trafficType ;
    // few other int parameters
};

struct flowHeader_end {
    // few other int parameters 
};

typedef struct flowHeaderA { 
    struct flowHeader_start s;
    int flowDirection; // Present ONLY if trafficType = TT_V6
    struct flowHeader_end e;
} t_flowHeaderA ;

typedef struct flowHeaderB {
    struct flowHeader_start s; struct flowHeader_end e;
} t_flowHeaderB ;

...然后重新排列一下演员表:

if (((struct flowHeader_start *)buf)->trafficType == TT_V6) {
    hdr = (t_flowHeaderA *) buf ; 
    flowDir = hdr->flowDirection ; 
} else {
    hdr = (t_flowHeaderB *) buf ;
    flowDir = FD_NA ; 
}

类型本身不依赖于条件,但两种可能的类型使用的位置取决于它。

直到struct flowHeader_start 结尾的两种类型的结构也保证完全相同(因为它们具有相同的第一个元素,并且结构必须从第一个元素开始而没有填充),因此您可以安全地在任一类型和struct flowHeader_start 之间进行转换,这意味着您可以在不知道缓冲区其余部分的形式的情况下测试放置在第一个块中的条件。

作为扩展,一些编译器可能还允许您将嵌套结构设为匿名,这样查看起来会更方便,不必通过中间的e 字段访问最后一个结构的元素(不记得是否该标准允许对命名类型进行此操作,我认为不是)。

【讨论】:

  • 这确实是我想到的选项之一。正如您正确指出的那样-它涉及更多检查-并且此代码位于快速路径中-我的性能受到了很小的影响。我希望避免这种惩罚。
  • ?这仅涉及一项检查,与问题中的代码相同..?
【解决方案2】:

不,你不能这样做。

C 是一种静态 语言,这就是为什么您必须首先声明事物的原因。编译器必须能够在程序运行之前生成代码,代码不能像这样根据运行时要求而改变。

您将不得不声明两种不同的结构,然后使用if 测试等根据运行时数据选择合适的结构。

【讨论】:

  • 谢谢 - 正如我在之前的评论中所写 - 如果检查对我来说可能会影响性能,请再做一次......我想避免那个。
【解决方案3】:

我认为你不能根据条件改变结构的大小。

  1. 您可以定义多个结构并相应地使用它们>

  2. 或定义那些应该有条件地出现在结构末尾的元素。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-11
    • 2017-12-08
    • 1970-01-01
    • 2019-06-18
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多