对于没有填充的结构,依赖sizeof是多么的便携
How portable is relying on sizeof for structures without padding
在我必须维护的代码中,一些数组序列化(例如std::vector<T>
)大致以如下方式发生:有一个array_t
结构没有填充:
#pragma pack(push, 1)
template <typename T, uint32_t N>
struct array_t
{
typedef T value_type;
static uint32_t const max_length = N;
uint32_t length;
value_type data[max_length];
value_type const & operator[](uint32_t k) { return data[k]; }
value_type & operator[](uint32_t k) { return data[k]; }
template <typename Container>
void from_container(Container const & c)
{
std::copy(c.begin(), c.end(), &(*this)[0]);
length = c.size();
}
template <typename Container>
Container to_container() const
{
return Container(&(*this)[0], &(*this)[length]);
}
};
#pragma pack(pop)
当需要通过网络发送此类数据类型时,会发生以下情况(非常简化):
template <typename T>
char * serialize(T const & data)
{
void * buf = std::malloc(sizeof(T));
std::memcpy(buf, &data, sizeof(T));
return reinterpret_cast<char *>(buf);
}
std::string const s("This is some string");
typedef array_t<char, 64> arr_str;
arr_str serial;
serial.from_container(s);
char * buf = serialize(serial);
network.send(buf); // frees the memory as well
在另一端,这种方法被称为:
template <typename T>
T deserialize(char * ptr)
{
T data;
std::memcpy(&data, ptr, sizeof(T));
std::free(ptr);
return data;
}
arr_str deserial = deserialize<arr_str>(buf);
我们不需要争辩说这不是序列化的最佳方式对象。我现在担心的是:它的便携性如何?这些人的评论方法说,这是保证工作在每个x86/x64系统-是那说法是真的吗?
这绝对不能移植到"任何x86"体系结构,除非您非常小心地在所有使用的数据结构中只使用定义大小的类型(uint16_t
、uint32_t
等)。
显然,如果您超出了x86系列处理器,那么您将面临字节排序的进一步问题。
你的问题很含糊。如果相同的二进制进行传输和接收,并且数据类型T是POD,那么这将起作用。
如果使用不同的二进制文件-使用不同的编译器、编译器版本、编译器设置等进行编译,那么数据类型的简单类型和简单结构可能是可以的(编译时间偏移和断言大小值得考虑),但许多事情并没有由标准规定,包括位字段的排序和填充方式(尤其是当它们跨越8/16/32位边界时)、布尔和枚举的大小(除非根据C++11指定)。许多标准库类型的布局也没有指定,所以即使您知道发送方和接收方都对所涉及的字符串大小使用了短字符串优化,也不能假设std::字符串会在传输中幸存下来。
相关文章:
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- ifstream什么都没读
- c++r值引用应用于函数指针
- 如果编译的源代码是特定于它编译的硬件的,我们如何分发它
- 如何仅使用对象名称打印特定于对象的成员
- 相当于LocaleMatcher的ICU4C
- 等<thing>效于char32_t
- 类似于strcat()的函数出现问题
- 如何将C++闭包与变量参数同时重用——类似于JavaScript
- 算术运算的结果类似于:C浮点变量中的1/3
- 相当于 pybind11 中的 boost::p ython py::scope().attr()
- 如何使我的 sizeof sum 结构与空参数包一起工作
- 如何将记忆应用于此递归函数?
- 静态类模板成员:将"sizeof"应用于不完整类型无效
- 将"sizeof"应用于不完整的类型(创建的类)无效
- 为什么 sizeof 内置类型(char 除外)在 C 和 C++ 中依赖于编译器?
- sizeof可以应用于未捕获的变量的lambda内部吗?还是这是一个编译器错误?
- sizeof(指针)依赖于对象类型吗?
- 计算固定数组中的元素数量(类似于sizeof)