Yes, you can think so. The analogy of the two ads you made correctly.
The lifetime of a compound literal is determined exactly by the declarative region in which it is specified and coincides with the lifetime of a regular variable of the same type, declared in the same context. That is, compound literal is simply an analogue of an unnamed variable of the corresponding type with the corresponding initializer.
However, one subtlety is associated with this in C language. Before the appearance of compound literals in C, there was no separate issue of the lifetime of objects declared, for example, in if branches
if (...) int a = 5; else int b = 42;
Since declarations in the C language are not and are never statements, such code is incorrect in C. To create a local declarative region in C that allows variable declarations, you must explicitly use {} . That is, the lifetime of ordinary (named) local objects in C is always outlined by an explicit block {} and is fully explained through the properties of the block.
However, with the emergence of compound literals in the language, the problem of lifetime arose in this form
int *a, *b, *c; if (a = (int []) { 1, 2, 3 }) b = (int []) { 4, 5, 6 }; else c = (int []) { 7, 8, 9 };
What should be the lifetime of such compound literals? Should they exist after if ?
Until now, neither the if nor its branches in the C language were separate declarative regions — as mentioned above, there was no need for that. However, after introducing the compound literals in C99, it was decided to follow the path C ++ and localize the lifetime of such literals. Now in C, both the if and its branches are implicit blocks that limit the lifetime of the compound literals created in them (and the scope of the names declared in them, see below).
Those. now, starting with C99, the above if equivalent
int *a, *b, *c; { if (a = (int []) { 1, 2, 3 }) { b = (int []) { 4, 5, 6 }; } else { c = (int []) { 7, 8, 9 }; } }
with all the consequences, i.e. with dangling pointer values. The same modification applies to other types of statements.
This, by the way, led to the loss of backward compatibility with "classic" C in a number of rarely used contexts. For example, in language C it is allowed to declare new types in sizeof and in castes. Using this opportunity in C89 / 90 you can write such code
int foo(int a) { if (a == sizeof(enum { A })) a = sizeof(enum { B }); else a = sizeof(enum { C }); return a + A + B + C; /* ОК в С89/90. Ошибка в C99 */ }
After C99, due to the introduction of implicit blocks in if , this code is no longer compiled.