Named parameters in C
blog.noctua-software.com
blog.noctua-software.com
func((struct somestruct){.x = 0, .y = 1});Sometimes it's a good way to go.
Combine this with struct definitions in function bodies and I see a great teamup with variadic functions.
Take a theoretical struct_printf, which prints out non promoted data with struct packing (not variadic stack packing, which requires type promotion)
/* Only uses va_start and va_arg to*/
void struct_printf(const char* format, ...){
...
}
void print_foo(){
struct foo_t{
float f;
uint16_t u2;
uint8_t x;
} input;
struct_printf("No type promotion here: %f %hu %hhx\n",
(struct foo_t){ .f = 0.1, .u2 = 1000, .x = 0xF2});
}
Now we can actually pass what we mean to pass without the compiler changing it.NOTE: After I wrote this I'm not actually sure what va_args does with a struct or how to get a pointer to the first member...
I think you would still need to know the exact type inside of struct_printf(), unless you knew exactly how the compiler would pack a struct onto the stack or registers, and that it was exactly the same as individual parameters.
Instead, you're supposed to #include <inttypes.h> and use:
"No type promotion here: %f %"PRIu16" %"PRIx8"\n"The solution is named arguments, but I'm not convinced the added complexity of this solution is a net improvement.
C is like that really. You really need to pay attention to detail when you're writing C. And if there's too much to worry about, it means you need to redesign and simplify the APIs and/or data you're dealing with.
If I encounter functions with lots of parameters in third party libraries I have to use, I will annotate each argument with a comment (after checking the documentation).
OVERKILL_TYPEDEF_PTR_T somefunc(TYPE1_T, TYPE2_PTR_T, void *);
I always document my functions in the headers, especially for private code only I will use. E.g. /*
* Like vfprintf(), but prepends a timestamp and the name of the current thread
* or process. The output FILE will be locked using lockf() while the
* timestamp, thread name, and message are written. The thread name can be set
* using set_threadname().
*/
int vfptmf(FILE *out, const char *format, va_list args);Given:
int price, quantity;
compare place_order(price, quantity);
with {
price_t px = { price };
quantity_t qx = { quantity };
place_order(qx, px);
}
More verbose (especially where, like above, the values weren't already wrapped), but catches a significant error.It does not permit reordering arguments like the struct approach does, and doesn't help where you have multiple arguments of the same type that it is unreasonable to distinguish.
It is however, a terrible example of how to write good code. Any code that hides the language or manipulates for syntactic sugar only adds complexity, bugs and decreases the maintenability of the code.
As someone already said, a solution in search of a problem.
Microsoft is committed to C++, as a means to improve systems programming safety with more modern languages.
Besides, the code makes use of GCC extensions.
But the code is neither ISO C99 nor C11. It uses a GNU C extension called “statement expressions”, which is not supported by MSVC.
Also, its preprocessor has quite a few problems. I think after removing statement exprs and running the code through a different PP, MSVC will compile it.
Of course, one could just simply use MinGW or Clang instead.