, 1 min read
C Pointer Surprises
An article by Krister Walfridsson on C pointers are not hardware pointers demonstrated that even adjacent integer variables having the same hardware address may compare unequal regarding C pointers.
See the following C program:
#include <stdio.h>
int main(int argc, char *argv[]) {
int x, y;
int *p = &x + 1;
int *q = &y;
printf("%p %p %d\n", (void*)p, (void*)q, p == q);
return 0;
}
You have to compile with optimization enabled, e.g., cc -O3
. Otherwise gcc
adds some stuff between variables. On AMD/Intel/ARM CPUs the output looks something like this:
0xbe849afc 0xbe849afc 0
I.e., the pointers point to the same address, but the pointer comparison gives "false".
Added 06-Aug-2017: As hinted by the comment given by Ashwin Nanjappa below, the compiler actually does not generate compare instructions, but rather just adds 0=false.
Disassembling
$ cc -Wall -O3 -c ptrcomp.c
$ objdump -d ptrcomp.o
gives
ptrcomp.o: file format elf64-x86-64
Disassembly of section .text.startup:
0000000000000000 <main>:
0: 48 83 ec 18 sub $0x18,%rsp
4: 48 8d 3d 00 00 00 00 lea 0x0(%rip),%rdi # b <main+0xb>
b: 31 c9 xor %ecx,%ecx
d: 48 8d 54 24 04 lea 0x4(%rsp),%rdx
12: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
19: 00 00
1b: 48 89 44 24 08 mov %rax,0x8(%rsp)
20: 31 c0 xor %eax,%eax
22: 48 89 d6 mov %rdx,%rsi
25: e8 00 00 00 00 callq 2a <main+0x2a>
2a: 48 8b 4c 24 08 mov 0x8(%rsp),%rcx
2f: 64 48 33 0c 25 28 00 xor %fs:0x28,%rcx
36: 00 00
38: 75 07 jne 41 <main+0x41>
3a: 31 c0 xor %eax,%eax
3c: 48 83 c4 18 add $0x18,%rsp
40: c3 retq
41: e8 00 00 00 00 callq 46 <main+0x46>
Xoring oneself gives zero.