wangdoc/clang-tutorial

Union 联合体的解释完全错误

BruceKangCN opened this issue · 1 comments

给联合体中的某一字段赋值并不会使之前赋值的字段失效,也不会禁止用户访问之前的字段,例如

typedef union {
  char c;
  int i;
} U;

U u = { .c = 'A' }; // u.i == 65

联合体一般在嵌入式中比较常用,用于使用不同的方式访问寄存器

typedef union {
  struct {
    unsigned char all_bits;
  };
  struct {
    unsigned char bit0 : 1;
    unsigned char bit1 : 1;
    unsigned char bit2 : 1;
    unsigned char bit3 : 1;
    unsigned char bit4 : 1;
    unsigned char bit5 : 1;
    unsigned char bit6 : 1;
    unsigned char bit7 : 1;
  };
} U;

这样就可以通过 all_bits 访问、修改整个寄存器的值,或者通过位名称访问、修改指定的位了

另外在 PyTorch 的 c10 模块中,还借助 union 实现了 BF16 数据类型

using int_repr_t = uint16_t;
using float_t = c10::BFloat16;

union {
  float_t f;
  int_repr_t i;
}

LibTorch 中,BF16、FP16 与 FP32 的转换是通过解释成无符号整形然后使用位运算实现的,如果不使用 union 的话就需要大量使用 std::bit_cast。而如果使用 union,只需对其整数字段取值、赋值即可,在使用浮点字段的时候相当于自动进行了一次 tsd::bit_cast


另外项目名中的 clang 容易与 LLVM 的 C 编译器前端 Clang 产生混淆,建议更名为 c-lang-tutorial

谢谢指出,原来的表达确实不对,已经改正。