我想知道是否没有人使用 union 序列化 boost::asio 发送器/接收器的结构。我已经搜索过一些东西,但我发现的(目前)都是像 this 或 this 这样的例子。
所以我是这样完成的:
struct ST {
short a;
long b;
float c;
char c[256];
}
...
void sender::send(const ST &_packet) {
union {
const ST &s;
char (&c)[sizeof(ST)];
}usc = {_packet};
socket.send_to(boost::asio::buffer(usc.c, sizeof(ST)), endpoint);
}
...
ST var = {1234, -1234, 1.4567, "some text"};
sercer.send(var);
所以我现在的问题是,对基本数据类型进行序列化是一种不好的做法吗?
我知道我不能直接发送可变大小的字符串,因此我可以使用 boost::serialization。
最佳答案
这确实是不好的做法。您发送的是(应该是)一个字节序列,其中包含系统 union 中任何内容的精确二进制表示。问题是:
- 您用 ST 填充 usc union ,但将其作为 char[] 访问,这会产生未定义的行为(但可能适用于所有常见系统)。
- 您可能希望以相反的顺序在接收端执行相同的操作。再次 UB,但可能有效。
- 麻烦来了:您以系统特定的格式发送数据,接收系统上的格式不必相同,对于相同的结构定义。这包括
- 整数类型的字节顺序(小/大端)
- 类型的大小,不仅仅是整数(例如 sizeof(long) 有时在 32 位到 64 位系统之间不同,或者在 64 位系统上的不同编译器之间不同)
- 填充字节
- sizeof(ST) 本身可能有显着差异
简单地说:只是不要这样做。如果您无论如何都在使用 boost::serialization,请将其用于整个 ST 结构,而不仅仅是其中的字符串。如果您的数据结构变得稍微复杂一点(例如,包含指针、具有非平凡的构造函数等),您无论如何都必须这样做。
关于c++ - 使用 union 作为 boost::asio 的序列化器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14877133/