Compound Literal Lifetime

6.5.2.5p5 says

If a composite literal extends beyond the body of the function, the object has a static storage duration; otherwise, it automatically storage time associated with the closing unit.

Is it right to interpret the "enclosing block" here as the "innermost enclosing block"? (Because if it’s not the innermost, what is it?) Why do gcc and clang behave as if its lifespan was a closing 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 with -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 
+5
source share
2 answers

There seems to be no good reason for this. I would just call it a compiler error.

+5
source

Consider the code:

 void whatever(void) { THING *p; ... if (condition1) p=&(THING){...whatever...}; ... doSomethingWith(p); } 

As the standard is written, a compound literal will be used only if assignment p is performed by a single non-compound expression controlled by if ; changing the code, so if managed compound statement will require significant rework:

 void whatever(void) { THING *p,temp_thing; ... if (condition1) { temp_thing = (THING){...whatever...}; // Or else temp_thing.field1 = value1; temp_thing.field2=value2; etc. p=&temp_thing; } ... doSomethingWith(p); } 

Such a requirement would substantially and uselessly undermine the usefulness of complex literals (since the code could have been written without them). A more reasonable rule indicates that the lifetime of a compound literal continues until the code leaves the function in which it was used, or the expression that creates it is re-executed, whichever happens first. Since the Standard allows compilers to extend the life of automatic objects, but they deem necessary, the fact that the compiler does this should not be considered a mistake. On the other hand, a quality compiler that is intentionally more useful than the standard requires should probably explicitly document this fact. Otherwise, future maintainers may claim that any programs that rely on such reasonable behavior are “defective” and that the compiler may be more “efficient” if it ceases to support them.

0
source

Source: https://habr.com/ru/post/1273917/


All Articles