Looks like non-deterministic results is a consequence of environment randomization policy that kernel uses when starts new program. Lets try next code:
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
int main(int argc, char **argv) {
char c;
uintptr_t addr = (uintptr_t)&c;
unsigned pagesize = (unsigned)sysconf(_SC_PAGE_SIZE);
printf("in-page offset: %u\n", (unsigned)(addr % pagesize));
return 0;
}
On my 64-bit Linux it gives next output:
$ ./a.out
in-page offset: 3247
$ ./a.out
in-page offset: 2063
$ ./a.out
in-page offset: 863
$ ./a.out
in-page offset: 1871
Each time c
gets new offset within its stack page, and knowing that kernel always allocates discrete number of pages for stack - it is easy to see that each time program has slightly different amount of allocated stack. Thus program described in the question has non-constant amount of stack for its frames per each invokation.
Being frankly I'm not sure if it is kernel who tunes initial value for stack pointer or maybe it is some trick from dynamic linker. Anyway - user code will run in randomized environment each time.