gpt4 book ai didi

c - 指向可变修改类型的指针的指针算法

转载 作者:行者123 更新时间:2023-12-04 15:12:33 24 4
gpt4 key购买 nike

以下是有效的 C 代码吗? ( godbolt )

#include <stddef.h>

ptrdiff_t f(size_t n, void *x, void *y)
{
if (!n) return 0;
typedef unsigned char element[n];
element *a = x, *b = y;
return a - b;
}
-Werror=pointer-arith叮当大声提示
<source>:8:14: error: subtraction of pointers to type 'element' (aka 'unsigned char [n]') of zero size has undefined behavior [-Werror,-Wpointer-arith]
return a - b;
~ ^ ~
而 gcc 编译代码却毫无怨言。
clang 认为正在发生的未定义行为是什么?这
减法的可能性为零,因此不是有效的
指向数组元素的指针或不同的东西?没有
正在执行数组访问,对吗?所以应该不是这样的……
如果代码确实表现出未定义的行为,是否有一种简单的方法可以
修改代码以使其完全符合,同时仍然使用指向
VM 类型?

最佳答案

如果您的编译器支持 VLA,则发布的代码是有效的 C 代码。请注意,C99 中引入的 VLA 在最新版本的 C 标准中已成为可选。
两者 gcc 叮当正确编译代码,可以使用 Godbolt's compiler explorer 验证.
还有叮当如果 n 的值不正确,则会发出有关潜在未定义行为的警告。参数恰好为空,无法识别此案例已通过显式测试处理。问题不在于减法的值,而在于类型的大小,即 0如果 n == 0 .此警告并不是真正的错误,而是实现质量问题。
也有争议的是a - b仅在 a 时才定义和 b指向同一个数组或刚过它的最后一个元素。因此 xy必须验证此约束并具有类型 unsigned char (*)[n]或兼容。此规则有一个异常(exception),用于将任何类型作为字符类型的数组进行访问,因此将指针传递到 int 的同一数组中。没问题,但调用 f 是不正确的(虽然可能无害)这边走:

int x, y;
ptrdiff_t dist = f(sizeof(int), &x, &y);
编译器可以自由地发布诊断消息来吸引程序员对潜在问题的关注,实际上,在许多情况下,对于初学者和高级程序员来说,这样的警告都是救命稻草。编译器选项,例如 -Wall , -Werror-Weverything非常有用,但在这种特殊情况下,需要添加 -Wno-pointer-arith允许 叮当如果 -Werror 编译此函数也很活跃。
另请注意,使用 C89 函数可以获得相同的结果:
ptrdiff_t f89(size_t n, void *x, void *y)
{
if (!n) return 0;
unsigned char *a = x, *b = y;
return (a - b) / n;
}

关于c - 指向可变修改类型的指针的指针算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64949298/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com