Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 未对准的负载是否由未定义的铸造行为引起?_C_Casting_Undefined Behavior_Memory Alignment - Fatal编程技术网

C 未对准的负载是否由未定义的铸造行为引起?

C 未对准的负载是否由未定义的铸造行为引起?,c,casting,undefined-behavior,memory-alignment,C,Casting,Undefined Behavior,Memory Alignment,是否由于未定义的行为造成的铸造导致荷载未对准 以下是我在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 her

是否由于未定义的行为造成的铸造导致荷载未对准


以下是我在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
              ^ 
这里是演员们发挥作用的地方:

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++;

  ...
}

相关,但我不相信上述问题的答案:


我认为你的具体问题的答案是“是”——虽然我不确定这是否具体针对演员阵容本身,但一般来说是针对未对齐的指针。buf_xor()的内部代码在我看来基本上没有问题,所以我想看看传入的地址是什么

在我看来,您不想使用未对齐的地址调用buf_xor()。如果不是这样的话(如果您在任何地方都使用对齐的地址调用but xor()),那么我会确保uintptr_t被定义为编译buf_xor()的地方以及调用它的地方相同的东西(特别是64位宽,基于您的输出)


最后一个个人意见是,由于您的buf_xor()实现需要在某些处理器/编译器实现上使用对齐指针作为参数,因此您可以通过更改签名来反映这一点(将void*更改为uintptpr_t*)——或者更改实现本身来优雅地处理,从而避免将来的一些麻烦,“手动”,所有架构上的地址都未对齐。

到错误对齐指针的转换本身未定义,而不仅仅是通过该指针的加载(C11(n1570)6.3.2.3 p7):

指向对象类型的指针可以转换为指向不同对象类型的指针。如果所引用类型的结果指针未正确对齐[…],则行为未定义

显示的代码也打破了严格的别名,因为指向的对象不太可能声明为
uintpttr\u t
(否则地址将正确对齐)

为了符合标准,可以使用
无符号字符


如果出于性能原因,应复制
uintpttr\u t
-大小的块,则可以使用
无符号字符
,直到地址正确对齐,然后再进行另一个循环复制
uintptpr\u t
。这应该通过联合或通过
memcpy
来完成,以避免混淆问题(如果大小不变,Gcc可以优化
memcpy
调用)。最后的字节可能需要再次通过
无符号字符
进行复制,以避免越界访问(读取
sizeof(uintptpr_\t)-1
字节超过数组不会导致问题(Glibc在多个位置执行此操作),但直写
dst
可能会写入另一个对象)。它可能有助于限制使用的指针。

这实际上是我正在分析和验收测试的GnuPG代码。我想解决调用方中的联合或对齐指针的问题。但是它在很多地方都完成了,因此使用
memcpy
将函数修复为临时函数变得更加容易。不过,我会将错误报告归档以提醒他们注意这个问题(请参阅)。这完全取决于您在该函数中显示的参数。如果看不到调用代码,就不可能回答这个问题。@Lundin-是这样吗?Clang已通知地址为0x7fff04fdd0e1。
0xxxxxxx1
是否曾经是循环中使用的
uintpttr\u t*
?或者我分析Clang的输出不正确?是的,但为什么是XXX1?必须向函数传递字符指针或其他内容。发布的代码中没有任何内容会导致未对齐,因为您在那里执行的所有指针算法都基于正确的类型。编辑了越界访问部分。在我喝第一杯咖啡之前,我不应该建议忽视UB。。。