jww*_*jww 7 c casting memory-alignment undefined-behavior
是否由于void*
未定义的行为导致错位负载?
以下是我对Clang及其消毒剂的看法:
bufhelp.h:146:29: runtime error: load of misaligned address 0x7fff04fdd0e1 for type 'const uintptr_t' (aka 'const unsigned long'), which requires 8 byte alignment
0x7fff04fdd0e1: note: pointer points here
00 00 00 66 66 6f 6f 62 61 72 34 32 46 4f 4f 42 41 52 31 37 66 6f 6f 62 61 72 34 33 46 4f 4f 42
^
Run Code Online (Sandbox Code Playgroud)
这是演员阵容发挥作用的地方:
buf_xor(void *_dst, const void *_src1, const void *_src2, size_t len)
{
...
ldst = (uintptr_t *)(void *)dst;
lsrc1 = (const uintptr_t *)(const void *)src1;
lsrc2 = (const uintptr_t *)(const void *)src2;
for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t))
*ldst++ = *lsrc1++ ^ *lsrc2++;
...
}
Run Code Online (Sandbox Code Playgroud)
相关,但我不相信上述问题的答案:
转换为错误对齐的指针本身是未定义的,不仅是通过该指针的加载(C11(n1570)6.3.2.3 p7):
指向对象类型的指针可以转换为指向不同对象类型的指针.如果生成的指针未正确对齐引用类型[...],则行为未定义.
显示的代码也会破坏严格的别名,因为指向的对象不太可能被声明为uintptr_t
(否则地址将正确对齐).
为了符合标准,unsigned char
可以使用.
如果uintptr_t
出于性能原因应复制-sized块,unsigned char
可以使用,直到地址正确对齐,然后再进行另一次循环复制uintptr_t
.这应该通过union或via memcpy
来完成,以避免出现混叠问题(memcpy
如果大小不变,Gcc可以优化调用).可能需要unsigned char
再次复制最后的字节以避免越界访问(sizeof(uintptr_t)-1
通过数组的读取字节不应导致问题(Glibc在几个地方执行此操作),但写入dst
可能写入另一个对象).它可能有助于对restrict
所用指针进行限定.
归档时间: |
|
查看次数: |
2810 次 |
最近记录: |