Search code examples
cgccclanglanguage-lawyercompound-literals

Lifetime of a compound literal


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

Solution

  • There does not seem to be any good reason for this. I would just call it a compiler bug.