So if anyone has any recommendations of oo in c projects i could checkout I would appreciate it.
So if anyone has any recommendations of oo in c projects i could checkout I would appreciate it.
void dothing(const dothingArgs& args);
...
dothing({ .arg1 = 1, .arg2 = someOtherThing });
Register colouring should make it run the same as regular args for the most part in optimized builds.
This has two benefits:
1) Changing the order of the struct args won't introduce ordering bugs like with function signatures.
2) Default arguments are more explicit and there's less chance of breakage as the argument list grows over time and gets more default values, as tends to happen.
And 2 drawbacks:
1) Passing complex types as arguments without copying can be tricky.
2) The compiler errors don't tell you specifically which arguments are broken, at least in g++. This one sucks the most imo.
The combination of type inference, pass by reference, and aggregate initialization shown here is only possible in C++, I think.
https://en.cppreference.com/w/cpp/language/aggregate_initial...
C++20 will get a fairly limited subset of the C99's designated init though.
void dothing(const dothingArgs args);
and then just passing it an anonymous struct that only briefly sits on the stack when you call
dothing({ .arg1 = 1, .arg2 = someOtherThing });
A reference would make sense if you already have a struct sitting somewhere else in your program, but if you're putting together the struct at the time you call the function, wouldn't it make more sense to just pass by value?
Though your question is kind of getting at r-values and move semantics, which is a solution to prevent copying the temp value both when calling the function and in its execution. You can read about it because it will take too long to explain it here.
Because of this, the statement "Changing the order of the struct args won't introduce ordering bugs like with function signatures" is actually not true - I know from experience that clang will sometimes just silently leave the struct uninitialized, which could lead to nasty bugs. The behavior can also vary between optimized and debug builds, so it might not surface when you run your unit tests, etc.
I believe that once C++20 is standardized both compilers will probably introduce warnings or errors to let you know when you've unintentionally initialized fields out of order, but for right now the feature is a landmine and I wouldn't recommend using it.
[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p032...
ie: int f(int a, int b) changed to f(int b, int a) works but the arguments will be wrong if the call site doesn't change.
f({ .a = 1, .b = 2}) will fail at the call site when the struct is changed to expect f({ .b = 2, .a = 1})
But yes, while ideally the order of declaration wouldn't matter, C++ is going the other way, being extremely strict about initialization order to avoid complex constructor errors. I wish POD types would be treated differently for those warnings/errors.
my_func((person_t){ .name = "John Doe", .age = 33 });
...by-pointer also works:
my_func(&(person_t){ .name = "John Doe", .age = 33 });
Any struct items which are not assigned a value will be zero-initialized (I wish it would be possible to define default-values in the struct declaration though).
I question the value of bringing OO principles into plain C though ;)