Why the output of this 'C' code is like this?

  • A+
Category:Languages

I have following C code:

#include<stdio.h> #include<stdlib.h> int main() {  int a[4] = {1,2,3,4};  int b[4] = {1,2,3,4};  int n = &b[3] - &a[2];  printf("%d/n", n);  return 0; } 

Why the value of n is -3? I don't have a pure explanation for that. How can the difference between the addresses of the variables be a -3? And why it is exactly -3?


While the C standard does not define the behavior when you subtract pointers to elements in different arrays, what seems to have happened is that your compiler put b in memory just before (at a lower address than) a. Thus, the memory layout looked like:

+------+------+------+------+------+------+------+------+ | b[0] | b[1] | b[2] | b[3] | a[0] | a[1] | a[2] | a[3] | +------+------+------+------+------+------+------+------+ 

Given this memory layout, &a[2] - &b[3] is +3 because a[2] is three elements later in memory than b[3]. Then &b[3] - &a[2] is -3 because b[3] is three elements earlier in memory than a[2]. (Note that simple pointer arithmetic like this that does not conform to the C standard can break because the compiler may perform various optimizations or because address arithmetic is complicated on some architectures. The C standard does not just not define the result of the subtraction; it does not define the behavior of the program at all once an undefined subtraction is performed.)

Many C implementations put objects on a stack (if they have automatic storage duration, rather than static, allocated, or thread), and it is common for the stack to start at a high memory address and grow toward lower addresses. So, if the compiler is simply allocating space for objects in the order you declare them (this is not to be expected generally; there are a number of reasons to do fancier things), then it effectively would put a on the stack first, then decrease the stack pointer, and then put b on the stack, so b ends up at a lower address than a.

Incidentally, the result of subtracting two pointers has size ptrdiff_t, which is not necessarily int, so it ought to be printed with printf("%td/n", n); rather than %d, and n should be declared with ptrdiff_t n; rather than int n;. The ptrdiff_t type is defined in the <stddef.h> header.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: