类型双关——编译器如何决定使用什么类型
Type punning - how does the compiler decide what type to use?
我在这里读到了这个关于决定endianness的问题,第一个答案让我有些困惑。
用于决定大端序的代码如下:
int is_big_endian(void)
{
union {
uint32_t i;
char c[4];
} bint = {0x01020304};
return bint.c[0] == 1;
}
我的问题是这里的编译器如何决定使用什么类型的十六进制数字数组?因为从技术上讲,它同样适用于uint32_t
和char[4]
。
为什么不将其存储在char[4]
中并跳过union
呢?
union
有什么我看不到的优点吗?我知道这叫做类型双关,但我看不出它在这里的优势。
我的问题是,这里的编译器如何决定对十六进制数字数组使用什么类型?
与数组和聚合类一样,第一个初始化程序初始化第一个成员;在这种情况下为CCD_ 6。(当然,与这些不同的是,拥有一个以上的初始化程序是没有意义的)。
为什么不直接将其存储在char[4]中并跳过并集呢?这里的工会有什么我看不到的优势吗?
这样做的目的是初始化4字节整数,然后使用char
数组检查各个字节以确定内存顺序。如果最高有效字节(0x01
)存储在第一个字节中,则系统为"big-endian";否则它就是"小endian"(或者可能是一些奇怪的东西)。
最初的C标准只允许为并集的第一个元素赋值。这意味着:0x1020304被分配给"i",而不是"c"。
最新的C标准允许分配给任何成员,如下所示:
union { ... } bint = { .c = {1,2,3,4} };
union { ... } bint2 = { .i = 0x1020304 };
但是,如前所述,如果没有给出名称,则将值分配给"i"。
因为您想将0x01020304
存储为无符号32位整数uint32_t i
,然后读取第一个字节char c[0]
。
相关文章:
- 我应该使用什么来代替void作为变体中的替代类型之一
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 标准 N3337 5.2.10 第 7 条中的C++"类型"是什么意思?
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 数据类型"struct seq<0, 1, 2>{}"含义是什么?
- 在自定义 std::vector-like 容器中处理指针和非指针模板类型的最佳方法是什么?
- 您应该在什么时候创建自己的异常类型
- C++ 未初始化的本地(非全局)int 数组中的元素类型到底是什么?
- 未命名的非类型模板参数有什么意义?
- 静态自动 constexpr t = { "red" , "black" , "green" } 是什么类型;派生到?
- 模板<>模板<类型名 T> 语法有什么用?
- 指针类型类成员的动态强制转换的恒定性是什么?
- 当 c++ 需要一种数据类型并获取另一种数据类型时会发生什么?
- 这是什么类型的C++语法,我应该采取什么步骤来理解这一点
- 返回类型在 C++ OOP 中是什么意思
- 如何声明一个标准::提升直方图的向量?提升直方图的类型是什么?
- 类名后跟括号的类型是什么
- 删除对象(具有不同类型)的引用时会发生什么情况?
- reinterpret_cast,只读访问,简单的可复制类型,会出什么问题?
- 当你只使用 return 时,函数返回什么类型;在 c++ 中