3

我一直认为,指针递增/递减是这样的操作:

 new_ptr=old_ptr+sizeof(type)*count 

所以使用 int * 它将是:

  old_ptr=0     //int *ptr=0
  count=1       //int count=1
  new_ptr=old_ptr+sizeof(int)*count = 0+4*1 = 0x0004  //ptr+=count; 

并且 void = 0 的大小,因此使用 += 增加 void_ptr 不应该改变它。但我可能弄错了。另一件事是 ++ 运算符,它会引发错误。那么如果 ++ 抛出错误,为什么 += 也不抛出呢?示例代码:

#include <stdio.h>
void tell(const char *s,int *i,void *v){
    printf("%s: \n int_ptr: %#x\n void_ptr: %#x\n",s,i,v);
}
int main(){
    int *int_ptr=0;
    void *void_ptr=0;
    tell("Before",int_ptr,void_ptr);
    int_ptr++;  //int_ptr=int_ptr+sizeof(int); = 0x 0004
    //void_ptr++;   //error: ISO C++ forbids incrementing a pointer of type 'void*'
    tell("After ++",int_ptr,void_ptr);
    int_ptr+=1; //int_ptr=int_ptr+sizeof(int)  =  0x0008
    void_ptr+=1;//void_ptr=void_ptr+sizeof(void)    WHY DOES THIS WORK AND ++ DOES NOT?!     = 0x0001 ?! should be 0x0000, because sizeof void = 0
    tell("After +=",int_ptr,void_ptr); //RESULT: void_ptr=0x1, so does that mean, that sizeof void is 1 and it is not 0
    return 0;
}

输出:

Before:
 int_ptr: 0
 void_ptr: 0
After ++:
 int_ptr: 0x4
 void_ptr: 0
After +=:
 int_ptr: 0x8
 void_ptr: 0x1

有人可以解释一下吗?

4

2 回答 2

5

void 指针的算术在 C 和 C++ 中都是非法的。一些编译器具有允许它的扩展。

在这种情况下,GCC 有一个指针算术扩展,它允许对 void 指针和函数指针进行算术运算,根据标准,这两者都是非法的。它将两者都视为它们指向大小为 1 的类型。

基本上,这是您应该在新代码中避免的兼容性黑客。

为什么 ++ 运算符会引发错误,而 += 不会,我不确定。++ 曾经使用此扩展在 GCC 中工作。可能是这个版本的 GCC 中的错误,或者 C++ 扩展的不一致应用程序。

于 2013-10-04T14:37:25.970 回答
0

那么如果 ++ 抛出错误,为什么 += 也不抛出呢?

为什么 GCC 行为不同,恕我直言,这是一个简单的人为错误的结果:在 GCC 源代码的某个位置使用了宏TYPE_PTROB_P,而它可能应该是TYPE_PTROBV_P.

于 2013-10-04T14:51:05.340 回答