4 ms·
Default values for structs, only taking effect when static or used with designated initializers, would be good enough imo, since you can always pass a struct to
by cozzyd 4y ago
Default values for structs, only taking effect when static or used with designated initializers, would be good enough imo, since you can always pass a struct to a function.
So you could do foo({.bar=1}) and the rest would be default initialized.
- flohofwoe 4y agoYep, this is also at the top of my wishlist to 'complete' the designated initializagtion feature: struct bla_t { int a = 23; const char* hello = "Hello World!"; }; ...and only allow comptime known constants for the default value declarations.
- pantalaimon 4y agoYou can already do struct bla_t { int a; const char* hello; } blub = { .a = 23, .hello = "Hello World!", };
- flohofwoe 4y agoNo that's just creating an item 'blub' of struct 'bla_t', it doesn't help with default values that the compiler could fill in with when using designated init instead of zeroes. To borrow from your example: struct bla_t { int a = 23; const char* hello = "Hello World!"; } blub = { .a = 46, }; The missing designated init item blub.hello would now be initialized to "Hello World!" by the compiler by looking up the default value in the struct declaration. Currently, missing designated init items are set to zero. And it would work in any other place where a bla_t is created: struct bla_t blob = {}; This would initialize blob to its default state of blob.a = 23 and blob.hello = "Hello World!".
- pantalaimon 4y agoBut this is the exact kind of implicit magic I’m happy that C does not have. If I look at a piece of code that does struct bla_t blub = { .a = 46, }; I know that everything except .a will be zero, without knowing anything about bla_t. With your proposal I would now get a 'helpful' default that might not be what I want at all.
- flohofwoe 4y agoThat's a fair point of course, but when you pass 'blub' into a library function, this function needs to fill in the zeroes with default values anyway, and that's just as opaque, and it causes extra runtime overhead which wouldn't be there if the compiler already knows the default values.
- pantalaimon 4y ago> this function needs to fill in the zeroes with default values anyway Wait - no. What's wrong with #define BLA_INIT_DEFAULT { .a = 23, .hello = "Hello World!", } struct bla_t blub = BLA_INIT_DEFAULT; blub.a = 42; That's what your proposal would do under the hood anyway, just more explicit.
- flohofwoe 4y agoYou can even change that to: #define BLA_DEFAULTS .a = 23, .hello = "Hello World!" struct bla_t blub = { BLA_DEFAULTS, .a = 42, }; ...because C99 allows designated initializers to show up multiple times, but that's all a bit too much macro magic for my taste, I'd really prefer the defaults in the struct declaration.
- pantalaimon 4y agoThis just saves you a single line of code compared to struct baz tmp = {.bar=1}; foo(&tmp);
- flohofwoe 4y agoThe point is that foo() now needs to check every struct item for being zero and use the default value instead. If the default values would be listed in the struct declaration, the compiler could fill those in when tmp is created, without any additional runtime overhead. It would also free up zero as being an actual value instead of standing for 'default value'.
- pantalaimon 4y agoThen just make a define with the default values #define FOO_INIT_DEFAULT {.bar=1} I don’t want some 'magic' struct that behaves different than all other structs on init. A static (default zero) struct lives in .bss, that entire section is zeroed on init. If you want to have default values, it goes to .data where it will consume some ROM.
- flohofwoe 4y agoIf you want your structs to be zero initialized, then you just wouldn't declare default values in the struct declaration, and everything would work as before. Also, once you initialize structs with values somewhere in the code (for instance with designated init), there's a high chance that the compiler will put a copy into the data section anyway, which is then memcpy'ed into the runtime struct (it depends on the compiler and compile options).
- rwmj 4y agoThat's how it works already, eg: #include <stdio.h> #include <stdlib.h> struct params { int a; void *p; }; void f (struct params p) { printf ("p.a = %d, p.p = %p\n", p.a, p.p); } int main (void) { f ((struct params){.a = 42}); f ((struct params){.p = f}); f ((struct params){}); exit (EXIT_SUCCESS); } Even though these are stack allocated, the missing fields are initialized to 0/NULL. The last case (no parameters) is new in C23. In C99 you had to use (struct params){0} to initialize it. https://en.cppreference.com/w/c/language/compound_literal https://en.cppreference.com/w/c/language/compound_literal