6.5.2.5p5 says
If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.
Am I correct to interpret "the enclosing block" here as "the innermost enclosing block"? (Because if it's not the innermost one, which is it?) Why are gcc and clang behaving as if the lifetime of a literal were its enclosing function?
Example:
long foo(long*);
void call_foo()
{
{foo(&(long){42});}
{foo(&(long){42});}
{foo(&(long){42});}
{foo(&(long){42});}
}
//for comparison
void call_foo2()
{
{long x=42;foo(&x);}
{long x=42;foo(&x);}
{long x=42;foo(&x);}
{long x=42;foo(&x);}
}
Code generated by gcc/clang at -O3:
call_foo:
sub rsp, 40
mov rdi, rsp
mov QWORD PTR [rsp], 42
call foo
lea rdi, [rsp+8]
mov QWORD PTR [rsp+8], 42
call foo
lea rdi, [rsp+16]
mov QWORD PTR [rsp+16], 42
call foo
lea rdi, [rsp+24]
mov QWORD PTR [rsp+24], 42
call foo
add rsp, 40
ret
call_foo2:
sub rsp, 24
lea rdi, [rsp+8]
mov QWORD PTR [rsp+8], 42
call foo
lea rdi, [rsp+8]
mov QWORD PTR [rsp+8], 42
call foo
lea rdi, [rsp+8]
mov QWORD PTR [rsp+8], 42
call foo
lea rdi, [rsp+8]
mov QWORD PTR [rsp+8], 42
call foo
add rsp, 24
ret
{ }
block where they are declared. Or if outside a function, they have file scope and static storage duration - just as any other variable. As for why you get that machine code, I don't know. Seems weird indeed. I would expect it to re-use the same stack area. – Northwest-std=c++11 -pedantic-errors
. – Northwest-x c
, but this question is only about C, not C++. (Practically, a locally generated program compiled withgcc
behaves the same in this regard as theg++ -x c
Compiler Explorer example.) – Fireguardlea
instruction followed by an address which changes by 0x11 for each call. Weird - I can't explain this. Could it be because of ASLR? – Northwest