u/Sad-Finish2729

Why does GCC on Windows allocate non-adjacent stack slots for local variables unless & or volatile is used?

#include <stdio.h>

void test01(){
    int b = 0x00454647;
     /* E F G */
    int a = 0x41424344;
     /* A B C D */

    // printf("%p %p\n", &b, &a);   // commented
    // volatile int b = ...;        // or this

    char *p1 = (char *)&a;
    printf("%s\n", p1);
}

Hi everyone,

I'm learning C on Windows using GCC (MinGW), and I noticed a strange behavior about stack layout.

Observation:

  • When I don't take the address of b (&b) and don't use volatile, the variables a and b are not adjacent in memory. When I print the string from &a, I get DCBA followed by garbage.
  • As soon as I add printf("%p", &b); or declare b as volatile, a and b become adjacent (differ by exactly 4 bytes), and I get DCBAGEF as expected.

Interestingly:

  • Clang (on Windows) allocates them adjacent even without & or volatile.
  • GCC on Linux also tends to put them next to each other by default.

Only GCC on Windows (MinGW) shows this "non-adjacent unless address is taken" behavior.

Questions:

  1. What exactly is GCC doing during stack slot allocation in this case?
  2. Why does taking the address (&) or using volatile change the layout so dramatically?
  3. Is this related to some Windows ABI / MinGW specific stack alignment or optimization pass?
  4. Is there any flag (besides -O0) that can make GCC behave more like Clang in terms of stack layout predictability?

I know that the C standard doesn't guarantee stack layout or variable order, but I'm curious about the implementation difference between GCC (Windows) vs Clang/GCC (Linux).

Any insight into GCC's internals (especially stack slot allocation, assign_stack_local, reload pass, etc.) would be greatly appreciated!

Thanks!

reddit.com
u/Sad-Finish2729 — 1 day ago