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
A compound literal is a postfix expression that provides an unnamed object whose value is given by an initializer list. The C99 language feature allows you to pass parameters to functions without the need for temporary variables.
6.26 Compound Literals As an extension, GCC supports compound literals in C90 mode and in C++, though the semantics are somewhat different in C++.
There does not seem to be any good reason for this. I would just call it a compiler bug.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With