严格的混叠规则和std::copy
Strict aliasing rules and std::copy
我有一个包含"序列化"数据的字符数组,我需要将其解释为'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也有同样的问题,这是"允许的"。
这是标准的编译代码还是我需要坚持使用内存?
EDIT:我应该补充一下,我很欣赏关于如何最好地做到这一点的答案,它们很有趣,但我的问题更多的是关于这是合法的而不是我如何做到这一点。
这相当于std::memcpy(&i, data, sizeof(int))
,并且存在依赖于端序和假设sizeof(int) <= sizeof(data)
的相同问题,这与平台相关。char *
不受严格混叠规则约束
为什么不直接写:
#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
然后,例如要获得{4, 5, 6, 7}
部分的int
,您可以这样写:
i = TO_INT(data+4);
注意:这不是用于复制粘贴的代码,它给出了一个想法。如果你有不同的系统,int
的大小不同,或者除了char *
之外,你可能会给宏其他类型的指针,你自己做错误检查。
满足您的需求吗?
int f (const char* x, size_t index)
{
const int* p = (const int*)x ;
return p[index] ;
}
gcc 4.5.2编译时没有任何警告,即使打开了-O3 -Wall
。
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- std::清洗和严格的混叠规则
- 是否使用示波器队列:: swap违反任何规则来清空std ::队列
- MISRA C++(规则 18-4-1)和动态内存分配 - 是否允许 std::string
- 使用经典重载解析规则创建依赖于 std::调用的重载集类
- c++11 严格别名规则是否允许通过 char *、char(&)[N],甚至 std::array<char、N> 和 -fstrict-aliasing -Wstrict-aliasi
- C STD :: Local Time Daylight节省时间规则(DST)欧洲与美国人
- "using namespace std;"是否免于过多代码规则?
- 将Javascript正则表达式模式转换为C++std::regex的规则
- 全局std::字符串和一个定义规则
- 为什么存在 C++11 std::initializer_list 构造函数重载规则
- 应将复制赋值运算符利用std::swap作为一般规则
- 确定与 std::function<R(T1,T2)兼容的函数类型集的规则>?
- 如何在std::map中插入项目而不违反MISRA C++2008必需规则5-2-12
- 不在异常中嵌入std::字符串的规则是否仍然适用于move构造函数
- 严格的混叠规则和std::copy
- 如何使用std::string的值作为Flex规则的模式