减去指针p – (p – 1)如何创建整数溢出?
这是代码:
#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节(数组和指针). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |