Re:Plain C API design, the real world Kobayashi Maru test
by mintplant on Sunday April 16, 2023 @02:51PM
(#35593108)
Composition?
For checked downcasts, you could include an enum type tag inside `context` and have something like `foo_context* as_foo_context(context* ctx)` for downcasts, which, if `context` is at the beginning of `foo_context`, could just check the tag and cast the `ctx` pointer to `foo_context*` (or do a little pointer arithmetic if `context` is somewhere else in the containing struct). Return `NULL` (or assert) if the tag doesn't match.
[ Parent
| on HN ]
Re:Plain C API design, the real world Kobayashi Maru test
by dromtrund on Sunday April 16, 2023 @04:16PM
(#35593877)
+1, this approach will also highlight cases where you're trying to generalize something that isn't as generic as you thought.
I'd argue that the need for downcasting in a method working on the inner context would also be a code smell, and that you might want to reconsider the context split. In some cases, there's no way around it (like async events), but it might be more appropriate to pass additional context or a callback instead, to avoid a circular dependency.
Re:Plain C API design, the real world Kobayashi Maru test
by uecker on Sunday April 16, 2023 @05:12PM
(#35594317)
I use this technique a lot and it is very powerful.
Re:Plain C API design, the real world Kobayashi Maru test
by zcbenz on Sunday April 16, 2023 @11:06PM
(#35596456)
Adding fields to context will break ABI compatibility.
To work around the problem, some libraries add padding fields, and some require passing the size of struct to determine ABI version.