这里发生了什么事?指针数学搞砸了?

时间:2019-05-08 02:24:09

标签: c

    int i = 0, j = 0;

int *a , *b;

a = &i + 1;
b = &j;

printf(" %p \n ",a);
printf(" %p \n ",b);

if(a==b)
printf(" yo \n");

输出:

0x7ffda8e133a4

0x7ffda8e133a4

a与b相同,但printf仍然不执行。

ideone link to this code

当我将a和b设为普通变量时,这很好用。 (int a,b;)

1 个答案:

答案 0 :(得分:4)

ISO/IEC 9899:201x

第6.5.6节等式运算符:

  
      
  1. 当且仅当都是空指针时,两个指针比较相等,两者都是指向同一对象的指针(包括指向对象和位于其开头的子对象的指针) )或函数,都指向同一数组对象的最后一个元素之后的指针,或一个指向一个数组对象的末尾的指针,另一个是指向不同数组对象的起点的指针。恰好紧跟着地址空间中的第一个数组对象
  2.   

但是又一次:

  
      
  1. 出于这些运算符的目的,指向不是数组元素的对象的指针的行为与指向长度为1且对象类型为其元素类型的数组的第一个元素的指针的行为相同。
  2.   

因此... ab的行为应与指向数组的指针相同,并且ij恰好在内存中彼此相邻。 ..然后&i + 1 可以指向jb)的第一个“数组元素”的开头。好吧,如果很大。我不会依靠的。也许在打包的结构中。


@OmG

  

代码的最新版本对我有用! [使用初始化的ij]

gcc 9.1 -O3,先依次2个printf()ret

        sub     rsp, 24
        mov     edi, OFFSET FLAT:.LC0
        xor     eax, eax
        lea     rsi, [rsp+12]
        mov     DWORD PTR [rsp+8], 0
        mov     DWORD PTR [rsp+12], 0
        call    printf                       ; <----------
        lea     rsi, [rsp+12]
        mov     edi, OFFSET FLAT:.LC0
        xor     eax, eax
        call    printf                       ; <----------
        xor     eax, eax
        add     rsp, 24
        ret                                  ; <----------

godbolt Compiler Explorer, gcc 9.1