gpt4 book ai didi

c - 减去指针 p - (p - 1) 如何造成整数溢出?

转载 作者:太空狗 更新时间:2023-10-29 16:01:43 26 4
gpt4 key购买 nike

代码如下:

#include <stdio.h>
int main()
{
int i = 3;
int *p = &i;
p - (p - 1);
return 0;
}

编译器 (gcc) 在外减法时发出整数溢出警告:

[user@comp c]$ gcc foo.c
foo.c: In function ‘main’:
foo.c:6:5: warning: integer overflow in expression [-Woverflow]
p - (p - 1);
^

正确的结果,1,是在我的机器上得到的。

为什么?

这是因为指针地址是无符号整数,但 ptrdiff_t 是有符号整数,无法处理那些大数字吗?

我看到了

p - (p);

p - (p + 1);

不要造成溢出。

我想了解幕后发生的事情。这是我在 stackoverflow 上的第一个问题,如果我的问题可以改进,请告诉我。

最佳答案

指针运算不是整数运算。它是根据数组元素的地址定义的。如果 p 指向数组的一个元素,则 p-1 指向同一数组的前一个元素。如果该元素不存在,则减法具有未定义的行为。

出于指针运算的目的,单个对象被视为 1 元素数组。指针可能指向数组的末尾,但这样的指针可能不会被取消引用。

int i = 3;
int *p = &i;

到目前为止,还不错; p 指向 i

p - (p - 1);

评估 p - 1 有未定义的行为。没有正确的结果。

编译器通常不会生成代码来在运行时检查指针算法的有效性。在典型的实现中,以上将产生 1 的“预期”结果。编译器甚至可能在编译时用文字 1 替换表达式——但在进行优化所需的分析时,它可能会注意到行为未定义并警告您。

至于为什么您会收到该特定消息,这是关于您的编译器的问题,它恰好是 gcc。我在 gcc 4.7.2 中没有收到该消息,但在 4.8.0 和 4.9.0 中都收到了。 (命令

gcc --version

告诉您您使用的是哪个版本)。 gcc 打印一些 警告消息是正确的,但该特定消息是不正确的,因为没有执行整数运算。 “整数溢出”消息是 gcc 中的一个错误,它也会导致它为有效代码打印虚假警告。我已经提交了 bug report ,目前预计会在4.8.4版本修复。

p - (p);

这是有效的(但括号是不必要的)。两个指针的减法产生它们指向的数组元素之间的距离(以元素为单位)。如果它们不指向同一个数组,或者刚好超过它的末尾,则行为是未定义的。 p - p,鉴于 p 是一个有效的指针,它只是 0(ptrdiff_t 类型)。

p - (p + 1);

同样有效。 p + 1 指向 i 的结尾,这是允许的。减法产生 -1,也是 ptrdiff_t 类型。

推荐阅读:comp.lang.c FAQ 的第 4 节(指针)和第 6 节(数组和指针) .

关于c - 减去指针 p - (p - 1) 如何造成整数溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23747641/

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