c - 除了节省空间之外,使用 union 体还有其他特别的优点吗?

标签 c embedded

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

请赐教并告知。

这里有一个供您思考的示例:

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


  struct{
    ...
  } stru2;


  struct{
    ...
  } stru3;


  struct{
    ...
  } stru4;

 }
}main_packet

最佳答案

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

union 最常见的用途是将它们用于类型双关,这意味着您可以写入一个 union 成员,然后通过另一个成员读取该数据。这是 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 中列出的严格别名的异常(exception)情况,这是明确定义的行为:

  • an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union)

关于c - 除了节省空间之外,使用 union 体还有其他特别的优点吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40210438/

相关文章:

c - 如何测量我的全局变量的总大小?

c - 使用 AVX2 查找元素索引 - 代码优化

ios - 在 Objective-C 中将两个 uint8_t 转换/组合为 int16_t

c - Delphi 记录和 C 结构

c - 处理内存访问时避免将整数转换为指针的最佳方法 (MISRA 2008)

C, 是否可以将宏分配给结构变量?

c - cudaHostRegister 是否等同于 mlock() 系统调用?

c# - 如何正确地将 unsigned char* 从 c dll 编码(marshal)至 c#

c - 如何将 u32_t 中的十六进制值转换为其相应的 char/ascii 值?

c - 我真的应该使用 make 吗?