加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

减去指针p – (p – 1)如何创建整数溢出?

发布时间:2020-12-16 09:52:18 所属栏目:百科 来源:网络整理
导读:这是代码: #include stdio.hint main(){ int i = 3; int *p = i; p - (p - 1); return 0;} 编译器(gcc)警告外部减法的整数溢出: [user@comp c]$gcc foo.cfoo.c: In function ‘main’:foo.c:6:5: warning: integer overflow in expression [-Woverflow] p
这是代码:

#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是一个有符号的int并且无法处理那些大数字?

我看到了

p - (p);

p - (p + 1);

不要引起溢出.

我试图了解幕后发生的事情.这是我关于stackoverflow的第一个问题,如果我的问题可以改进,请告诉我.

解决方法

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

出于指针运算的目的,单个对象被视为1元素数组.指针可以指向刚好超过数组的末尾,但是这样的指针可能不会被解除引用.

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

到现在为止还挺好; p指向我.

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超过i的结尾,这是允许的.减法产生-1,同样是ptrdiff_t类型.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读