除了节省空间,使用工会的任何其他特殊优势?

时间:2016-10-24 03:51:38

标签: c embedded

在嵌入式编程中,通常有时会在一个联合中放置多达15个结构。这是一种常见的做法,包括我在内的大多数人都认为节省空间是因为RAM太小而且太珍贵。但现在我想知道,还有其他考虑因素吗?例如,速度?

请启发并告知。

这是你想法的一个例子:

typedef struct
{
 union
 { 
  struct{
    ...
  } stru1;


  struct{
    ...
  } stru2;


  struct{
    ...
  } stru3;


  struct{
    ...
  } stru4;

 }
}main_packet

2 个答案:

答案 0 :(得分:4)

使用联合来“节省空间”,即使用它来创建变体,通常被认为是不好的做法(例如被MISRA-C禁止),我建议不做任何事情。变体类型的存在几乎总是程序设计糟糕的表现。

联合的最常见目的是将它们用于类型双关语,这意味着您可以写入一个联盟成员,然后通过另一个成员读取该数据。这是C中明确定义的行为,在进行与硬件相关的编程时非常有用。

例如,您可以执行以下操作:

typedef union
{
  uint32_t u32;
  uint8_t  u8 [4];
} my32_t;

my32_t my32;
my32.u32 = 1;

if(my32.u8[0] == 1)
{
  puts("little endian");
}
else
{
  puts("big endian");
}

工会也可用于躲避the strict aliasing rules。像这样的代码会调用未定义的行为:

uint32_t u32 = 1;
uint16_t u16 = *(uint16_t*)&u32;  // bad, strict aliasing violation

为避免此错误,可以将代码重写为:

typedef union
{
  uint32_t u32;
  uint16_t u16;
} something_t;

something_t x;
x.u32 = 1;
uint16_t u16 = x.u16;

根据6.5 / 7中列出的严格别名的例外情况,这是明确定义的行为:

  
      
  • 一种聚合或联合类型,包括其成员中的上述类型之一(包括递归地,一个成员)   subaggregate或contains union)
  •   

答案 1 :(得分:0)

动态内存分配(malloc / free)是节省空间的一般方法,通过将内存重用于生命周期不重叠的数据结构。工会是一种非常不灵活,难以维护的方法。它们只应用于malloc / free的时间开销真正不可接受的特殊情况。

工会也被用来提供"原始"如果你用C ++编码,那将是一个类层次结构的野兽。而不是:

class A { ... };
class B : public A { ... };
class C : public A { ... };
class D : public A { ... };
你写道:

struct H
  {
    struct A a;
    enum { Really_B, Really_C, Really_D } really;
    union
      {
        struct B b;
        struct C c;
        struct D d;
      };
  };

在C ++中,您使用虚函数来获取B,C,D所需的不同行为。在C中,您使用较少的可维护开关或if / else如果构造使用"派生类型"标识符字段("真的"在这种情况下)。

也可以使用联合而不是指针转换来将原始字节解释为不同的类型:

typedef union
  {
    float fp;
    struct
      {
        unsigned fraction : 23;
        unsigned exponent : 8;
        unsigned sign     : 1;
      }
    fld;
  }
Floating_point;