8 comments

[ 2.9 ms ] story [ 23.7 ms ] thread
GCC generates essentially the same assembly for C++'s std::optional<int> with the exception that the result can't be returned in a register (a problem which will go away if the function is inlined)

https://gcc.godbolt.org/z/vfzK9Toz4

> Here, instead of handling the error condition, I create an lvalue that points nowhere in case of an error because it then corresponds to (({ (void)0; })), relying on the null sanitizer to transform it into a run-time trap for safety.

Isn't this undefined behavior?

At this point I always wonder why people who write stuff like this don't just move to a different language. You are introducing insane amounts of hidden complexity(see also the other posts on that blog). For something that just exists in other languages. Or maybe this is just a fun puzzle for the author, in which case it's totally fine.
BTW: I think what me annoys me about this comment is the claim that this would be "insane amounts of hidden complexity" . If you you look at the article, it four simple one-line macros:

#define maybe(T) struct maybe_##T { bool ok; T value; }

#define maybe_just(T, x) (maybe(T)){ .value = (x), .ok = true }

#define maybe_nothing(T) (maybe(T)){ .value = (T){ }, .ok = false }

#define maybe_value(T, x) (({ maybe(T) _p = &(x); _p->ok ? &_p->value : (void*)0; }))

Please compare this to your other languages.

It might be more useful with a signature like maybe_divide -> maybe(int) -> maybe(int) -> maybe(int) ... and then a set of operations over maybe, and functions/macros for and_then(), or_else(), etc. It would be interesting to see how ergonomic it could get.
I love seeing the creative ways people implement these types of, if I can say, high level abstractions in C. Thanks for sharing
Clever, but it misses the very goal of option/maybe types: forcing the user to check the result. In this implementation nothing stops the user from omitting the "if (p.ok)" part and directly using "p.value".

It could work if "maybe(T)" is completely opaque to the user; both checking and accessing its payload must happen through helper macros; the checking macro ticks an invisible flag if ok; the accessing macro returns the payload only if the invisible flag is ticked, otherwise it triggers a runtime error/exception.

Not impossible. However, you would need to replace all "p.ok" with "maybe_check(p)", which is not unreasonable, and all "p.value" with "maybe_value(p)", which might be too much for the final user...