0

Does the following zero out a list and then add the first entry? Or does it just add the first entry to handlers?

 Logger = (struct logger) {.level=INFO, .format=DEFAULT_FORMAT, .num_handlers=1, .handlers[0]=stdout};

For example, does this do:

Logger.handlers = {0};
Logger.handlers[0] = stdout;

Or is there no clearing involved?

Barmar
  • 741,623
  • 53
  • 500
  • 612
carl.hiass
  • 1,526
  • 1
  • 6
  • 26
  • If `.handlers[]` has more than one element, then `.handlers[0]=stdout` and all other elements are initialized zero by default. See: [C11 Standard § 6.7.9 Initialization (p21)](http://port70.net/~nsz/c/c11/n1570.html#6.7.9p21) – David C. Rankin Mar 18 '21 at 06:04
  • @DavidC.Rankin Could you post that as an answer? Because there's another answer that says the opposite. Also, note that this is a compound literal, not a variable initialization. But it inherits the semantics. – Barmar Mar 18 '21 at 17:22
  • @Barmar sure, give me a second and I'll write it up. – David C. Rankin Mar 18 '21 at 18:30

2 Answers2

1

For example, does this do:

Logger.handlers = {0};
Logger.handlers[0] = stdout;

Answer: Yes (but not specifically in that order)

There are three standard sections (actually 4 if you take the section that specifically makes the following two applicable to "aggregate objects" (struct and arrays)) under the section C11 Standard § 6.7.9 - Initialization. Your case asks "What happens to the other elements of Logger.handlers if only Logger.handlers[0] = stdout; is provided a value during initialization?"

To answer that question, you need to look at § 6.7.9 Initialization (p19) and § 6.7.9 Initialization (p21)

The first specifies how initialization of structs occurs in "list order" and that "all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration." So if you provide fewer than all values to fully initialize a subobject, those not provided a value are initialized as if they have static storage duration. (objects with static storage duration, not explicitly initialized, are initialized to zero (or NULL, as appropriate for type), See: § 6.7.9 Initialization (p10))

Paragraph 21 specifically covers your case where fewer initializers are provided within a brace enclosed list -- "all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration." § 6.7.9 Initialization (p21)

So putting it altogether, what actually happens for the initialization of Logger.handlers is the first element is initialized to stdout and that all other elements are initialized NULL (since stdout is a pointer of type FILE*). So what you would actually have is:

Logger.handlers[CONST] = { stdout, NULL, NULL, ... };

Look things over (read all of § 6.7.9), and let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • thanks for this. Jeez the spec reads like its geared towards machines and has such an alien syntax... – carl.hiass Mar 18 '21 at 19:18
  • There are a couple of section that leave you scratching your head. But you get used to them in time. One of the "less-articulately" worded sections has to do with the Strict Aliasing rule, [C11 Standard - §6.5 Expressions (p6,7)](http://port70.net/~nsz/c/c11/n1570.html#6.5p6) .... good luck with that one ... `:)` – David C. Rankin Mar 18 '21 at 22:46
0

The latter Logger.handlers[0] = stdout;. This is why the API has a .num_handlers field to tell called code know how many of the handlers are valid.

Allan Wind
  • 23,068
  • 5
  • 28
  • 38
  • @Allen -- well, I wrote that code, so I'm not so sure you can trust it. The `.num_handlers` was added to make cleanup easier. – carl.hiass Mar 18 '21 at 06:21
  • The other option is for the handlers to end the list with a magic value (i.e. NULL) . Similar to how string is terminated by '\0' or could be struct with a char * and len. – Allan Wind Mar 18 '21 at 06:23