动态类型转换为变量类型

假设,我有一个类,例如:

struct A
{
  uint8_t f1;
  int16_t f2;
};

我需要从内存缓冲区数据中设置它的成员值,例如:

uint8_t * memory=device.getBufferedDataFromDevice();

A a;
a.f1=*((uint8_t*)&memory[someAddress]);
a.f2=*((int16_t*)&memory[someOtherAddress]);

但我想让它更灵活,并避免显式类型转换,以便有可能在不更改其余代码的情况下更改声明中的类型。当然,我可以通过以下方式实现它:

memcpy((void*)&a.f1, (void*)&memory[someAddress], sizeof(A::f1));
memcpy((void*)&a.f1, (void*)&memory[someAddress], sizeof(A::f1));

但我也想避免为简单类型调用函数,如 1-4 字节长整数(我有),因为简单的赋值可以编译为单个 CPU 指令。请指教,实现这一点的C++方式是什么?

谢谢!

回答

memcpy每个现代 C++ 编译器都完全理解memcpy.

或者,您知道,关闭优化。

这里既没有理由void*强制转换为,也没有理由使用危险的 C 风格转换。

std::memcpy(&a.f1, &memory[someAddress], sizeof(a.f1));

这是一种符合标准的方法来移动表示与a.f1over相同类型数据的内存a.f1,假设a.f1可以简单地复制。(注意我使用了相同的标记序列 -- a.f1-- 用于写入的内容和大小。)

编译器会将其优化为适当的程序集,并且不会有函数调用开销。

Live example,可以看到生成的程序集。

现在,您可能会反对“但不能保证!”。

C++ 标准不包括a+b不会作为循环实现的保证int r = 0; for (int i = 0; i < a; ++i){++r;} for (int i = 0; i < b; ++i){++r;}

你不能假设你的 C++ 编译器是敌对的。

现有的 C++ 编译器优化了对memcpy. 编写代码假设它不会发生是浪费时间。

你也可以写一个稍微安全一点的memcpy

template<class Dest>
void memcpyT( Dest* dest, void const* src ) {
  static_assert( std::is_trivially_copyable_v<Dest> );
  memcpy( dest, src, sizeof(Dest) );
}

我在上面的示例中包含了它作为替代。

  • @BbIKTOP 如果您认为 `memcpy(&amp;a, &amp;b, 7)` 明确告诉 C++ 使用链接,那您就错了。一种常见的误解是,您脑中在 C++ 程序代码到汇编之间的幼稚映射就是 C++ 的定义。它不是。C++ 标准库定义了编译单元,C++/C 标准库的主体不是编译单元,您的工具链如何工作的事实是标准之外的实现细节。C/C++ 标准描述了调用 `memcpy` 的作用,它没有解决它被链接或其他任何问题。

以上是动态类型转换为变量类型的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>