5 ms·
C needs default parameters. Where the compiler puts on stack the default value, whenever the function call doesn't include it. Guess that won't compromise wit
by habibur 4y ago
C needs default parameters.
Where the compiler puts on stack the default value, whenever the function call doesn't include it.
Guess that won't compromise with anything.
- JonChesterfield 4y agoHow would you have those work with function pointers?
- habibur 4y agoGood point.
- kangalioo 4y agoI see the point. Out of curiosity, I thought up some approaches: - disallow making function pointers of functions with default params - require explicitly passing all params when used as a function pointer - generate a trampoline function that generates the default params and use that as the function pointer - somehow include the default param values as part of the function pointer type
- unwind 4y agoWouldn't that be just as hard as for any other function? The name of a function (a bit like the name of an array) evaluates to basically a function pointer value, there is little difference between the two calls here: int foo(int a, int b) { return a + b; } int main(void) { printf("Direct: %d\n", foo(1, 2)); int (*ptr)(int, int) = foo; printf("Indirect: %d\n", ptr(1, 2)); return 0; } of course default arguments, if added, would have to be part of the function pointer type as well, making the above: int foo(int a = 1, int b = 2) // NOT REAL CODE, FANTASY SYNTAX { return a + b; } int main(void) { printf("Direct default: %d\n", foo()); int (*ptr)(int a = 1, int b = 2) = foo; // NOT REAL CODE, FANTASY SYNTAX printf("Indirect default: %d\n", ptr()); return 0; } Unnamed function arguments would look silly (`int (ptr)(int = 1, int = 2)`?), but I would be radical then and only support default argument values for named arguments, probably. Edit: fixed a typo in the code, changed in-code comment.
- JonChesterfield 4y agoEncoding the defaults in the type seems valid. Interesting alternative to name mangling + cast to select the variant.
- cozzyd 4y agoDefault 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.
- Cloudef 4y agoPlease no initialization fiasco from C++ ... http://mikelui.io/2019/01/03/seriously-bonkers.html http://mikelui.io/2019/01/03/seriously-bonkers.html
- JonChesterfield 4y agoSeems unrelated? Though attribute((constructor)) will give you that fiasco in vendor extended C if you miss it.
- flohofwoe 4y agoThis makes only sense when it comes with named parameters which can be provided in any order, not the half-assed default-parameter implementation from C++.
- masklinn 4y ago> Where the compiler puts on stack the default value, whenever the function call doesn't include it. So if a dynamically linked library uses default values, and you make use of them, and the dynamically linked library decides to change its default values (e.g. a crypto library switches to more secure defaults), you don’t get the update until you recompile your own code. That doesn’t sound great. Isn’t it C# which uses this strategy, of embedding the defaults in the caller? PS: I don’t think C is defined in terms of stack, and modern calling conventions use registers for at least the first few arguments.
- Joker_vD 4y agoThat's IIRC how C++ also does this, so... yeah, it's not great but lots of things are not great about C and/or C++ and the standard advice is "yeah, don't do that if that hurts".