将 memcpy-ing 结构转换为字节,并且即使使用填充也能保证相同的数据吗?并将字节解释为结构?

Will memcpy-ing a struct to bytes, and back guarantee the same data even with padding? And interpreting bytes as struct?

一个非常简单的例子

#include <stdint.h>

typedef struct {
  uint8_t a;
  uint64_t b;
} Test;

// With no struct *packing* sizeof(Test) == 16 on my machine

// Create some data
uint8_t buf[sizeof(Test)];
Test test;
test.a = 255;
test.b = 1234567890;

memcpy(buf, &test, sizeof(Test));

// Now copy the data from buf into a new structure
Test test2;
memcpy(&test2, buf, sizeof(Test));

// Interpret the bytes as a struct Test
Test* test_ptr = (Test*)buf;

// If all of this is done on the same machine (no transmitting data across different sets of hardware)
// are we guaranteed to always have the following conditions
test.a == test2.a;
test.a == test_ptr->a;
test.b == test2.b;
test.b == test_ptr->b;

这在我的机器上有效,但我只是想知道它是否恰好是 compiler/architecture 的幸运实例。另外,如果有一个更复杂的数据结构,在不同的地方有更多的填充,会发生什么?

这一切都发生在同一台机器上,所以不用担心通过 serial/tcp/etc link 发送 buf 并误解字节。

是的,因为具有相同类型的不同对象的内存布局必须相同。

typedef struct {
  uint8_t a;
  uint64_t b;
} Test;

Test t1, t2;
uint8_t buf[sizeof(Test)];
t1.a = 255;
t2.b = 1234567890;

memcpy(buf, &t1, sizeof(t1));

memcpy(&t2, buf, sizeof(t2));

t2 & t1 将具有相同的内存占用。

This is all happening on the same machine, so not worrying about sending buf over a serial/tcp/etc link and mis-interpreting the bytes.

如果 link 的两边有相同的程序(即使用相同的编译器和编译选项编译),那将是安全的。

否则不安全,必须序列化数据

PS。我错过了一件事:

// Interpret the bytes as a struct Test
Test* test_ptr = (Test*)buf;

是指针指针双关,是UB。请改用 memcpy 或联合双关语。

不要害怕 memcpy 因为编译器在大多数情况下会优化它并且这种分配或双关将以非常有效的方式完成。