Probably some people know what compound literals are and can use this in practice.

However, I had a question about the internal representation of these literals.

Well, suppose I have this entry: int *a = (int[]){10, 20, 30}; - so I created and assigned to the pointer the address of an array of type int created somewhere in the memory.

Is it possible to assume that the record: int *a = (int[]){10, 20, 30}; - equivalent to the following entry?

 int arr[] = {10,20,30}; int *parr = arr; 

What is the scheme for assigning the compound literal address?

  • What does an "assignment scheme" mean? - Vlad from Moscow
  • @VladfromMoscow means how the compound literals mechanism is represented inside - MaximPro
  • What is the mechanism? It is not known how arrays are created? What is the problem? - Vlad from Moscow
  • @VladfromMoscow Well, you're downstairs sort of like described it - MaximPro

2 answers 2

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.

  • Comments are not intended for extended discussion; conversation moved to chat . - Nick Volynkin

A compound literal creates an unnamed object. Its storage duration depends on whether it is defined inside the function, or outside the function. If a compound literal is declared outside a function, then it has a statistical storage duration, and otherwise an automatic storage duration.

This entry

 int *a = (int[]){10, 20, 30}; 

is equivalent to

 int arr[] = {10,20,30}; int *a = arr; 
  • That is, if in the second variant we change the elements through the pointer, then these changes will affect the named array. This means that the unnamed array in the composite literal will also be modified if there are changes through the pointer. I understand correctly?! - MaximPro
  • @MaximPro Yes, you understand correctly. You can check it yourself. - Vlad from Moscow
  • Check navryatli for how can I see an unnamed array except through a pointer to it =) (Although if we take the statement that we refer to this array with pointer then everything is OK) By the way, are these constructions equivalent in speed? - MaximPro
  • @MaximPro Why are you so worried about mythic speed? This speed does not depend on designs at all. - Vlad from Moscow
  • Just interested to know no more :) - MaximPro