-6
#include <stdio.h>
int main(int argc, char const *argv[]) {
     /* code */
     int a[2][3][2] = {{{1,2},
                        {9,8},
                        {3,7}},
                       {{2,2},
                        {1,4},
                        {5,4}}};
     int i,j,k;
     printf("\n\n\n");
     for (i = 0; i < 2; ++i) {
          for (j = 0; j < 3; ++j) {
               for (k = 0; k < 2; ++k) {
                    printf("\t &a[%d][%d][%d] = %p  ",i,j,k,(&a[i][j][k]) ) ;
               }
               printf("\n");
          }
          printf("\n");
     }


     printf("\t a[1] = %p  a[0] = %p\n",a[1],a[0] );
     printf("\t a[1] - a[0] = %d\n",a[1] - a[0] );            //  ????

     printf("\t a[1][0] = %p  a[0][0]= %p\n",a[1][0],a[0][0] );

     printf("\t a[1][0] - a[0][0] = %d\n", a[1][0] - a[0][0]);      // ??????


     return 0;
}

O/P:

 &a[0][0][0] = 0023FF04      &a[0][0][1] = 0023FF08  
 &a[0][1][0] = 0023FF0C      &a[0][1][1] = 0023FF10  
 &a[0][2][0] = 0023FF14      &a[0][2][1] = 0023FF18  

 &a[1][0][0] = 0023FF1C      &a[1][0][1] = 0023FF20  
 &a[1][1][0] = 0023FF24      &a[1][1][1] = 0023FF28  
 &a[1][2][0] = 0023FF2C      &a[1][2][1] = 0023FF30  

 a[1] = 0023FF1C  a[0] = 0023FF04
 a[1] - a[0] = 3
 a[1][0] = 0023FF1C  a[0][0]= 0023FF04
 a[1][0] - a[0][0] = 6

I understand the decay of pointers. In the above code a[1] and a[0] both decay to the first locations of each 2d arrays, inside actual array a. When we take the difference of these two pointers they behave like pointers to 1d array ((int*)[]) of 2 elements.

because we are dealing with a 3d array in this c program, we four types of possible pointer types.

  1. (int*)[][][]
  2. (int*)[][]
  3. (int*)[]
  4. (int*)

In terms of pointer's value, all types decay into single element location.

My doubt is, even after decay what are possible TYPES of a[],a[][],&a,a etc. which can produce different result. (as in the case of pointer difference in the above program)

Debashish
  • 1,155
  • 19
  • 34
  • 1
    Printing pointer values with `%u` or `%d` format specifiers is *undefined behavior*. End of story. – AnT stands with Russia Dec 20 '16 at 00:06
  • thanks @AnT ! anyway it is printing in my system. Whatever it may be, addresses are following a definite sequence, and that undefined behavior is not at all my doubt or concern here. – Debashish Dec 20 '16 at 00:09
  • 1
    You should have been around long enough to know better than to post screenshots of code. You didn't even provide alt-text for people using screen readers. – Hermann Döppes Dec 20 '16 at 00:12
  • sorry for that, this my 2nd QS with screen shot, (first one no one said anything :) ) – Debashish Dec 20 '16 at 00:15
  • 2
    @Debashish: The "not at all my doubt or concern here" excuse might be applicable when the danger of UB is purely conceptual and unlikely to occur in practice. In this case the danger is real (considering the possibility of size difference between `int` and pointer types), for which reason I have to override: the UB is definitely your "doubt and concern here". In its current form your question makes no sense. – AnT stands with Russia Dec 20 '16 at 00:15
  • ok, @Stargateur , I have edited now – Debashish Dec 20 '16 at 00:30
  • @AnT, I don't have much knowledge regarding this UB with %u or %d. I will surely read some existing question that topic. But for now, I just want to know, type mapping with a particular syntax. with &/[] or without etc. – Debashish Dec 20 '16 at 00:35
  • yes, and with &a[1] - &a[0] , it prints 1 – Debashish Dec 20 '16 at 00:51

1 Answers1

1

Note that a is not a pointer is an array.

So when you subtract a pointer to an another pointer. The result is not really an address, It's numbers of element between them. The type of the result is ptrdiff_t and you should print it with %td.

So when you do &a[1] - &a[0], you ask how many int [][] there are between &a[1] and &a[0] and the answer is 1.

But when you subtract a[1][0] with a[0][0] or a[1] with a[0], you have a undefined behavior because:

When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements.

a[1][0] and a[0][0] or a[1] and a[0] are not the same array/pointer. So you should not subtract them. But like I say a is an array so you have some result like 6 or 3. There are some special think about an array. But this is just a "luck", it's undefined behavior.

You can only do that

&a[i] - &a[j];
&a[i][j] - &a[i][k];
&a[i][j][k] - &a[i][j][l];

In your case, because a is an array:

assert(&a[2] - &a[0] == sizeof a / sizeof *a);

Learn more here and here.

Feel free to tell me I'm wrong. I'm not sure of myself in this answer.

Community
  • 1
  • 1
Stargateur
  • 24,473
  • 8
  • 65
  • 91