rhino-- rhino-- - 2 months ago 31
C Question

Char pointer subtraction in C

I have read about integer pointer subtraction in C in this thread: Pointer subtraction confusion, which was simple enough to grasp and test out.

However, I tried to replicate a similar scenario with a char* but the results that I get did not make much sense.

Here's the scenario that I tried:

#include <stdio.h>
#include <string.h>

int main() {

char a_arr[16] = "";
char *a = a_arr;
char b_arr[1] = "";
char *b = b_arr;

printf("\nThe amount by which they differ is: %d\n", a-b);
// a-b = 1, which makes sense since they are 1 char away

return 0;
}


The next thing that I tried is what I'm having trouble understanding

#include <stdio.h>
#include <string.h>

int main() {

char a_arr[16] = "";
char *a = a_arr;
char b_arr[2] = "";
char *b = b_arr;

printf("\nThe amount by which they differ is: %d\n", a-b);
// a-b = 16, which doesn't really make sense to me..

return 0;
}


My guess is that there is some padding stuff going on from the compiler's end which I thought shouldn't be the case since it is a char array and there would be no need for alignment..

I'm not sure why it is 16 bytes.. Any help is much appreciated!

I have used the following online interface to compile and run this piece of code:
http://www.tutorialspoint.com/compile_c_online.php

cxw cxw
Answer

In this example, a_arr, a, b_arr, and b are probably all allocated on the stack. The compiler doesn't have to give you any particular guarantees about the arrangement of variables on the stack. So the compiler might be padding to multiples of 16 bytes, or might be introducing other data between a and b, or might be saving register values in between a and b, or ... .

That is why, as the commenters pointed out, the spec doesn't guarantee the results of subtracting pointers belonging to two different arrays. The good news is that you usually won't need to do so unless you are writing an OS or standard library :) .

Edit Also, the arrangement of memory, and what is kept in a register vs. on the stack, may change depending on your optimization level. I don't think that's probably a factor here, but it's something to keep in mind.