c++ - 在 C++ 中将结构类型转换为整数,反之亦然

标签 c++ optimization struct casting bit-fields

所以,我看过这个帖子 Type casting struct to integer c++关于如何在整数和结构(位域)之间进行转换,毫无疑问,编写适当的转换函数或重载相关的转换运算符是涉及操作系统的任何情况的方法。 然而,当为只运行一个闪存镜像的小型嵌入式系统编写固件时,情况可能会有所不同,因为安全性不是那么重要,而性能才是。 因为每次编译我的代码时我都可以测试代码是否正常工作(意味着位域的位按照我期望的方式排列),所以这里的答案可能不同。

所以,我的问题是,是否有一种“正确”的方式在位域和 unsigned int 之间进行转换,在 g++ 中编译为无操作(当编译器知道这些位在内存中正确排列时,移位可能会被优化掉).

这是原始问题的摘录:

struct {
    int part1 : 10;
    int part2 : 6;
    int part3 : 16;
} word;

然后我可以将 part2 设置为等于请求的任何值,并将其他部分设置为 0。

word.part1 = 0; 
word.part2 = 9;
word.part3 = 0;

我现在想采用该结构,并将其转换为单个 32 位整数。我确实通过强制转换来编译它,但它似乎不是一种非常优雅或安全的数据转换方式。

int x = *reinterpret_cast<int*>(&word);

编辑: 现在,一段时间后,我学到了一些东西:

1) 通过指针转换的类型双关(改变数据的解释)是自 C99 和 C++98 以来未定义的行为。这些语言更改引入了严格的别名规则(它们允许编译器推断数据只能通过兼容类型的指针访问)以实现更好的优化。实际上,编译器不需要保持访问之间的顺序(或者根本不需要进行非类型访问)。对于大多数情况,这似乎不会出现 [直接] 问题,但是当使用更高的优化设置时(对于 gcc,即 -O,其中包括 -fstrict-aliasing),这将成为一个问题。 有关示例,请参阅 https://blog.regehr.org/archives/959

2) 使用 union 进行类型双关似乎也涉及 C++ 中的未定义行为,但不是 C(参见 https://stackoverflow.com/a/25672839/4360539),但是 GCC(可能还有其他)确实明确允许它:(参见 https://gcc.gnu.org/bugs/#nonbugs)。

3) 在 C++ 中进行类型双关的唯一真正可靠的方法似乎是使用 memcpy 将数据复制到新位置并执行任何要完成的操作,然后使用另一个 memcpy 返回更改。我确实在 SO 的某个地方读到过,GCC(或者可能是大多数编译器)应该能够将 memcpy 优化为寄存器大小数据类型的单纯寄存器拷贝,但我再也找不到它了。

因此,如果您可以确定代码是由支持通过 union 进行类型双关的编译器编译的,那么在这里最好的做法可能是使用 union 。对于其他情况,需要进一步调查编译器如何处理更大的数据结构和 memcpy,如果这真的涉及来回复制,最好坚持按位运算。

最佳答案

union {
    struct {
        int part1: 10;
        int part2: 6;
        int part3: 16;
    } parts;
    int whole;
} word;

然后只需使用 word.whole

关于c++ - 在 C++ 中将结构类型转换为整数,反之亦然,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31659340/

相关文章:

c++ - 如何使用 Crypto++ 解析 ZIP 文件?

python - 正则表达式性能Python

c - 如何在 Main() 之前创建数组/结构并在 C 中对其进行初始化

c - 在结构中添加字符

c - 指针数组的段错误

c++ - 如何删除窗口的标题和边框,以及如何制作自定义样式的 UI?

c++ - Qt:带有可移动小部件的窗口

c++ - 是否可以将 C++11 参数传递给 Buildroot 配置?

javascript - wuic javascript优化版本号计算

optimization - SIMD 指令降低 CPU 频率