gpt4 book ai didi

c++ - reinterpret_cast 和结构对齐

转载 作者:太空狗 更新时间:2023-10-29 21:15:31 29 4
gpt4 key购买 nike

有什么安全的方法可以将整数转换为结构体吗?

举个例子:

struct Colour
{
uint8_t A;
uint8_t R;
uint8_t G;
uint8_t B;
};

然后我转换为整数或从整数转换:

uint32_t myInteger
Colour* myColour = reinterpret_cast<Colour*>(&myInteger);
uint32_t* myInteger2 = reinterpret_cast<uint32_t*>(myColour);

如果我的结构被填充,那么这将不起作用,有什么方法可以保证它起作用吗?

我知道这可能不是标准的,但我更喜欢对主要编译器(Visual Studio 和 GCC)的支持,而不是一些移位解决方法,这已经在这里得到回答:Type casting struct to integer c++ .

最佳答案

考虑到评论中给出的限制(只关心 Windows 和 Linux 上的 VC++ 和 gcc),并假设您愿意将其进一步限制为“在 x86 和可能的 ARM 上运行”,您可能很容易通过通过添加 pragma 来确保不会在结构中填充:

#pragma pack(push, 1)
struct Colour
{
uint8_t A;
uint8_t R;
uint8_t G;
uint8_t B;
};
#pragma pack(pop)

请注意,如果您不关心与 VC++ 的兼容性,您可能希望以不同的方式执行此操作(gcc/g++ 有一个 __attribute__(aligned(1)) 否则可能是首选)。

reinterpret_cast 而言,有一个相当简单的规则:操作数和目标类型必须始终是指针或引用(好吧,您可以传递泛左值的名称,但是什么是used 是对那个对象的引用)——这里的整个想法是得到一些引用原始对象的东西,但是“查看”它就好像它是一个不同的类型,要做到这一点,你必须传递一些给出的东西访问操作数,而不仅仅是它的值。

如果您想要的结果是一个值(而不是引用或指针),您可以解引用该结果,并将该解引用的结果分配给您的目标。

uint32_t value = *reinterpret_cast<uint32_t *>(&some_color_object);

或:

color c = *reinterpret_cast<Color *>(&some_uint32_t);

鉴于引用的性质,其中一些可能被隐藏:

color c = reinterpret_cast<Color &>(some_uint32_t);

这里有一段快速的测试代码,用于进行一些转换并测试/显示结果(使用指针和引用,无论其值(value)如何):

#include <iostream>
#include <cassert>

#pragma pack(push, 1)
struct Colour
{
uint8_t A;
uint8_t R;
uint8_t G;
uint8_t B;

bool operator==(Colour const &e) const {
return A == e.A && R == e.R && G == e.G && B == e.B;
}

friend std::ostream &operator<<(std::ostream &os, Colour const &c) {
return os << std::hex << (int)c.A << "\t" << (int)c.R << "\t" << (int)c.G << "\t" << (int)c.B;
}
};
#pragma pack(pop)

int main() {
Colour c{ 1,2,3,4 };

uint32_t x = *reinterpret_cast<uint32_t *>(&c);

uint32_t y = 0x12345678;

Colour d = *reinterpret_cast<Colour *>(&y);

Colour e = reinterpret_cast<Colour &>(y);

assert(d == e);
std::cout << d << "\n";
}

不过请注意上面给出的限制。我已经用 VC++ (2015) 和 g++ (5.3) 对此进行了测试,我猜它可能会在这些编译器的其他版本上工作——但是像这样的代码在保证方式上没有太多东西.

它也完全有可能在不同的 CPU 上使用这些编译器实现收支平衡。特别是,Colouruint32_t 的对齐要求可能不同,因此在具有对齐要求的 CPU 上,它可能无法工作(甚至在 Intel 上,对齐可能会影响速度)。

关于c++ - reinterpret_cast 和结构对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37555815/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com