Maybe I'm misunderstanding you, but it's precisely because I have no knowledge of the stack frame's layout that I didn't expect the pointers to be equal.
That's where you are going wrong. You have no guarantee that the compiler places a and b next to each other, let alone in a defined order with a at a higher address than b such that one integer width beyond the end of b you find a.
Expecting one thing is wrong. You are expecting the one thing that the comparison always returns false. You should not expect anything. The comparison result could be true or false.
H:\>cl /O2 pointereq.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26431 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
pointereq.c
Microsoft (R) Incremental Linker Version 14.14.26431.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:pointereq.exe
pointereq.obj
H:\>.\pointereq
00CFFA20 00CFFA20 1
H:\>
You are confusing "did not expect them to be equal", which is what the OP wrote, with "expected them to be not equal", which is what you are railing against.
With /O2 optimisation I get:
00B1F99C 00B1F9A4 0