2

What is the difference between the following two initializations for a Struct?

Car ford = {
    .name = "Ford F-150",
    .price = 25000
};

And:

Car dodge = (Car) {
    .name = "Ram",
    .price = 1000
};

From Compiler Explorer, it looks like the two produce the same code:

enter image description here


What does the (StructName) do when preceding the struct? It seems its necessary when doing complex initializations such as:

CarPtr mazda = & (Car) {
    .name = "Mazda",
    .price = 20000
};

Also related, to the two answers from Possible to initialize/assign a struct pointer?.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
David542
  • 104,438
  • 178
  • 489
  • 842
  • See this Q/A about [compound literals](https://stackoverflow.com/q/330793/10871073). Perhaps not the best post, but there are many others on compound literals in C. – Adrian Mole Jan 06 '21 at 22:23
  • It's not necessary when initializing a struct variable. You need it when initializing a pointer, because the pointer needs an object to point to, and the compound literal creates an object. – Barmar Jan 06 '21 at 22:25
  • https://en.cppreference.com/w/c/language/compound_literal – Barmar Jan 06 '21 at 22:26
  • @Barmar wouldn't the object be `{...}` ? Why would the `(ObjType)` be needed to specify that? – David542 Jan 06 '21 at 22:28
  • 2
    You can't create an object with just `{...}`. That's an initializer list, so it can only be used when initializing a struct. Compound literals were invented to allow anonymous objects to be created. – Barmar Jan 06 '21 at 22:29

1 Answers1

2

In this declaration

Car dodge = (Car) {
    .name = "Ram",
    .price = 1000
};

there are created two objects of the type Car. The first one is the unnamed compound literal

(Car) {
    .name = "Ram",
    .price = 1000
}

that is used to initialize another named object dodge.

From C Standard (6.5.2.5 Compound literals)

3 A postfix expression that consists of a parenthesized type name followed by a braceenclosed list of initializers is a compound literal. It provides an unnamed object whose value is given by the initializer list.

In fact it is similar to the following declarations

Car ford = {
    .name = "Ford F-150",
    .price = 25000
};

Car dodge = ford;

The difference is that in the last example we created one more named object.

From the C Standard (6.7.9 Initialization)

13 The initializer for a structure or union object that has automatic storage duration shall be either an initializer list as described below, or a single expression that has compatible structure or union type. In the latter case, the initial value of the object, including unnamed members, is that of the expression.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • would both initializations take up the same amount of memory in storage, or does creating the second object double it or? – David542 Jan 06 '21 at 22:30
  • 1
    @David542 The compound literal will be alive in the scope where it is defined. That is as I wrote you created two objects. – Vlad from Moscow Jan 06 '21 at 22:33