Kir*_*rov 13 c c++ strict-aliasing reinterpret-cast
我读的越多,我就越困惑.
相关问题的最后一个问题与我的问题最接近,但是我对所有关于对象生命周期的问题感到困惑,尤其是 - 只读或不读.
直截了当.如我错了请纠正我.
这很好,gcc没有发出警告,我正试图" 通过" 读取类型T(uint32_t)char*:
uint32_t num = 0x01020304;
char* buff = reinterpret_cast< char* >( &num );
Run Code Online (Sandbox Code Playgroud)
但这是"坏"(也是一个警告),我正在尝试"反过来":
char buff[ 4 ] = { 0x1, 0x2, 0x3, 0x4 };
uint32_t num = *reinterpret_cast< uint32_t* >( buff );
Run Code Online (Sandbox Code Playgroud)
第二个如何与第一个不同,特别是当我们谈论重新排序指令(用于优化)时?另外,添加const不会以任何方式改变这种情况.
或者这只是一条直接规则,它明确指出:"这可以在一个方向完成,但在另一个方向不能完成"?我在标准中找不到任何相关内容(特别是在C++ 11标准中搜索过).
C和C++是否相同(因为我读了一条评论,暗示它与2种语言不同)?
我曾经union"解决"这个问题,但仍然看起来并非 100%正常,因为标准无法保证(这表明我只能依赖于最后一次修改的值union).
所以,经过大量阅读,我现在更加困惑.我想只是memcpy"好"的解决方案?
相关问题:
编辑
现实世界的情况:我有一个第三方库(http://www.fastcrypto.org/),它计算UMAC并返回值char[ 4 ].然后我需要将其转换为uint32_t.而且,顺便说一句,lib使用的东西((UINT32 *)pc->nonce)[0] = ((UINT32 *)nonce)[0]很多.无论如何.
另外,我问的是什么是对的,什么是错的以及为什么.不仅仅是关于重新排序,优化等等(有趣的是,-O0没有警告,只有-O2).
请注意:我知道大/小端情况.情况并非如此.我真的想忽略这里的字节序."严格的别名规则"听起来像是非常严肃的事情,远比错误的字节序严重得多.我的意思是 - 就像访问/修改内存一样,不应该被触及; 任何一种UB都可以.
标准(C和C++)的引用将非常感激.我找不到任何关于别名规则或任何相关的内容.
第二个如何与第一个不同,特别是当我们谈论重新排序指令(用于优化)时?
问题在于编译器使用规则来确定是否允许这样的优化.在第二种情况下,您尝试char[]通过不兼容的指针类型读取对象,这是未定义的行为; 因此,编译器可能会重新排序读取和写入(或执行您可能不期望的任何其他操作).
尽管看起来不自然,但你真的不得不考虑你认为编译器可能如何优化,并且只是遵守规则.
或者这只是一条直接规则,它明确指出:"这可以在一个方向完成,但在另一个方向不能完成"?我在标准中找不到任何相关内容(特别是在C++ 11标准中搜索过).
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf第3.10章第10段.
在C99中,我认为也是C11,它是6.5第7段.
C和C++都允许通过char *(或者特别是类型的左值char)访问任何对象类型.它们不允许char通过任意类型访问对象.所以是的,规则是一种"单向"规则.
我使用union来"解决"这个问题,这看起来仍然不是100%正常,因为标准不能保证(这表明我只能依赖于最后修改的值).
尽管该标准的措辞非常模糊,但在C99(及以后)中,很明显(至少从C99 TC3开始)意图是允许通过联合进行类型惩罚.但是,您必须通过联合执行所有访问(特别是您不能仅仅为了类型惩罚而'为了存在而构建联合').
返回的值在char [4]中.然后我需要将其转换为uint32_t
只需使用memcpy或手动将字节移动到正确的位置,以防字节排序成为问题.好的编译器无论如何都可以优化它(是的,甚至是调用memcpy).
| 归档时间: |
|
| 查看次数: |
812 次 |
| 最近记录: |