[Clang] memory allocation

Hi,

Could anyone please help me understand why Clang reallocates the same memory address for different variables while their lifetime intersect?

Here is an example code:

#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <alloca.h>

/* Checking information */

static int solutions = {
1,
0,
0,
2,
10, /* 5 /
4,
40,
92,
352,
724, /
10 */
2680,
14200,
73712,
365596,
};
#define MAX_SOLUTIONS sizeof(solutions)/sizeof(int)

int total_count;
int sharedVar = 0;

int ok(int n, char *a)
{
int i, j;
char p, q;
printf(“jjjjjjjjj: %d, %p\n”, n,&j);
for (i = 0; i < n; i++) {
p = a[i];

for (j = i + 1; j < n; j++) {
q = a[j];
if (q == p || q == p - (j - i) || q == p + (j - i))
return 0;
}
}
return 1;
}

void nqueens (int n, int j, char *a, int solutions)
{
int i,res;
sharedVar = sharedVar * j - n;
if (n == j) {
/
good solution, count it */
*solutions = 1;
return;
}
printf(“solutions: %d, %p\n”, j, &solutions);
*solutions = 0;

/* try each possible position for queen */
for (i = 0; i < n; i++) {
a[j] = (char) i;
if (ok(j + 1, a)) {
nqueens(n, j + 1, a,&res);
*solutions += res;
}
}
}

int main()
{
int size = 3;
char *a;
// printf(“total_count: %p\n”, &total_count);
total_count=0;
a = (char *)alloca(size * sizeof(char));
printf("Computing N-Queens algorithm (n=%d) ", size);
sharedVar = -5;
nqueens(size, 0, a, &total_count);
printf(“completed!\n”);
printf(“sharedVar: %d\n”, sharedVar);
}

When I compile the program with clang -O0 variable j in function ok has the same memory address as th variable solutions in function nqueens.

However, compiling it with gcc, they have different memory addresses.

Any help is appreciated!

Best Regards,
Mohammad

You printed &j and &solutions - did you mean to print ‘solutions’ instead of ‘&solutions’ Because ‘solutions’ and ‘j’ are both local variables in distinct function calls (‘ok’ is called, then ‘nqueens’ is called - so they can both use/reuse the same stack space for their local variables).

Thanks David for your reply!

However, OK is called inside nqueens. So, the same stack space cannot be used/reused for both of them.

Best,
Mohammad

nqueens is also called inside nqueens because it's a recursive
implementation, and it's those two calls within nqueens that reuse the
stack space. Notice that the reuse is *after* ok gets called.

Cheers.

Tim.

I see it now.

But, why do they have different memory addresses when compiled with -O1?

Is there a specific optimization that prevents using/reusing the same stack space?

Tnx!

The stack space is being reused, it just happens that those two
particular local variables don't get the same slot at higher
optimization levels.

Each function has a bunch of registers it needs to preserve that go on
the stack, additional local spill slots for variables it wants to keep
around but doesn't have enough registers for, and the real declared
local variables. All three of those variables change with optimization
level:

  + More efficient code might use fewer callee-saved registers,
leading to less saving at the beginning of a function.
  + More efficient use of values might get rid of the need to save
them for later, or leave registers free to hold them when needed.
  + Some local variables can be completely promoted to registers,
never using the stack at all.

And those changes very quickly mean that a specific local variable
will change its address.

Cheers.

Tim.