2


Many of us know that this works:

struct data_s
{
    uint32_t p_1;
    uint32_t p_2;
    uint32_t p_3;
    uint32_t p_4;
};

void foo(struct data_s data)
{
    printf("p1: %d\r\n", data.p_1);
    printf("p2: %d\r\n", data.p_2);
    printf("p3: %d\r\n", data.p_3);
    printf("p4: %d\r\n", data.p_4);
}

int main(void)
{
    foo((struct data_s){
            .p_1 = 1,
            .p_2 = 2,
            .p_3 = 3,
            .p_4 = 4});
}

I have seen this many times, but now cannot find anything in C reference manual about it. Is this construct standard or implementation defined?

Also, that type casting is kinda odd, because it is more like "I will tell compiler how and what to allocate and how to arrange it" than "cast that type to this type". Will the data layout in memory of the argument passed to function will be exactly the same as of object created by struct data_s obj;?

  • Is it type casting, or construction? – Tim Randall Sep 05 '18 at 15:36
  • @TimRandall no, it is not. – 0___________ Sep 05 '18 at 15:40
  • @TimRandall It depends what you mean by "construction". It's a source code construction in the same way that a string literal is a source code construction. It certainly is not a type cast. – Ian Abbott Sep 05 '18 at 15:53
  • See [Possible to declare an array in function argument](https://stackoverflow.com/questions/52159776), which references the C standard where compound literals are defined, and is itself a duplicate of [Why can't I pass constant arrays as arguments](https://stackoverflow.com/questions/36797540/), also discussing compound literals. I suspect there are earlier relevant Q&A too, but haven't hunted them down (yet). – Jonathan Leffler Sep 05 '18 at 16:49
  • _Many of us know_ this is not an anonymous `struct`, but a compound literal. And there is no type casting involved. – too honest for this site Sep 05 '18 at 17:19
  • Note that the data passed to the function will be the same if you use `(struct data_s){ .p_4 = 4, .p_1 = 1, .p_3 = 2, .p_2 = 2 }` — the order of the data is determined by the layout of the structure when you use designated initializers. – Jonathan Leffler Sep 06 '18 at 06:01

1 Answers1

4

This is the compound literal.

I was introduced in C99 and there is no difference between it and other constants and literals.

From web:

The compound literal expression constructs an unnamed object of the type specified by type and initializes it as specified by initializer-list.

The type of the compound literal is type (except when type is an array of unknown size; its size is deduced from the initializer-list as in array initialization).

The value category of a compound literal is lvalue (its address can be taken).

The unnamed object to which the compound literal evaluates has static storage duration if the compound literal occurs at file scope and automatic storage duration if the compound literal occurs at block scope (in which case the object's lifetime ends at the end of the enclosing block).

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0___________
  • 60,014
  • 4
  • 34
  • 74