【发布时间】:2019-07-24 15:29:04
【问题描述】:
我正在实现memcpy() 的一个版本,以便能够将它与volatile 一起使用。
使用char * 是否安全,还是需要unsigned char *?
volatile void *memcpy_v(volatile void *dest, const volatile void *src, size_t n)
{
const volatile char *src_c = (const volatile char *)src;
volatile char *dest_c = (volatile char *)dest;
for (size_t i = 0; i < n; i++) {
dest_c[i] = src_c[i];
}
return dest;
}
如果缓冲区的任何单元格中的数据是> INT8_MAX(我认为可能是UB),我认为unsigned 应该是避免溢出问题所必需的。
【问题讨论】:
-
为什么你会认为它会是 UB?是否都允许访问所有位,而不管这些位基于特定类型可能代表什么数字?
-
好的,不管它最初是什么,它都在重新解释数据,对吧?该值可能是未定义的,但总体结果是您将其原封不动地返回,并且不使用该值,所以它最终是定义的行为,对吧?
-
未定义的行为不会得到“未定义”;这是没有意义的。但我也没有看到你在这里感知 UB 的位置。不要只是“我认为可能是 UB”,请扩展以清楚地和详细地呈现您的问题。
-
您正在读取一个可能完全是
(uint8_t)200的值,并且在您将其取消引用为(可能是signed)char *的那一刻,该值神奇地转换为负值。我从来不需要做任何类型的双关语,所以我不知道什么是允许的,什么是不允许的,但这至少对我来说似乎很奇怪。 -
你也许可以证明普通的
char是安全的,但是仅仅使用unsigned char就可以省去你所有的努力。 (如果有问题,它可能会在实现中显示-0值/表示,其中普通char已签名并且不使用2 的补码。我怀疑是否存在任何此类系统。)
标签: c pointers casting char unsigned