我有一个包含“序列化”数据的字符数组,我需要将其解释为'int'。先前我只是将一个指向该位置的指针转换为'int *'并取消引用以获取int数据,但是虽然它对我来说效果很好但它违反了严格的别名规则,因此未定义行为。
所以现在我使用memcpy将字节复制到int中,我认为这不是未定义的行为。但是我可以使用“std :: copy”吗?
例如
char data[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int i;
std::copy(data, data+sizeof(int), reinterpret_cast<char*>(&i));
这本身并没有打破严格的别名规则,但任何可能的实现都会这样做......但是memcpy也有同样的问题并且是“允许的”。
这是标准的编译代码还是我需要坚持使用memcpy?
编辑:我应该补充一点,我指出了如何最好地做到这一点的答案,它们很有趣,但我的问题更多的是关于这是合法的而不是如何能够我这样做。
答案 0 :(得分:4)
这等同于std::memcpy(&i, data, sizeof(int))
,并且遇到依赖于字节序的相同问题以及sizeof(int) <= sizeof(data)
的假设,它们是平台相关的。 char *
免于严格别名规则。
答案 1 :(得分:0)
为什么不写:
#if __YOU_DEFINE_IF_LITTLE_ENDIAN__
#define TO_INT(d) ((((int)(d)[0]))|
(((int)(d)[1])<<8)|
(((int)(d)[2])<<16)|
(((int)(d)[3])<<24))
#else
#define TO_INT(d) ((((int)(d)[3]))|
(((int)(d)[2])<<8)|
(((int)(d)[1])<<16)|
(((int)(d)[0])<<24))
#endif
然后,例如,为了获得代码的int
部分的{4, 5, 6, 7}
,您可以写下:
i = TO_INT(data+4);
注意:这不是复制粘贴的代码,它提供了一个想法。如果您有int
不同大小的不同系统,或者可以在char *
旁边为宏提供其他类型的指针,请执行自己的错误检查。
答案 2 :(得分:-1)
这是否符合您的需求?
int f (const char* x, size_t index)
{
const int* p = (const int*)x ;
return p[index] ;
}
gcc 4.5.2在没有任何警告的情况下编译它,即使-O3 -Wall
已开启。