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.
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)
Proving the point that better type system and abstractions don't necessarly produce bad Assembly, and if constexpr is used, there won't be anything on the final executable other than the actual value.
Except that it is much more safer to use the type system than pre-processor glue based on text replacements, with more interesting error messages than templates.
> 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.
In standard C yes. But any decent C compiler will offer stronger guarantees than the minimum that the standard requires, and presumably the "null sanitizer" they're referring to is one of them.
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.
You don’t always get to choose your language. Especially in the embedded/firmware area of software development, C is the most widely available option, if not the only option besides ASM shrugs
Unless you are talking about PIC and similar CPUs, there is hardly a modern 16 bit CPU that doesn't have a C++ compiler available as well, assuming that we still consider 16 bit modern for whatever reason.
Heck I learned to program in C++, back when DR-DOS 5 was the latest version, and all I had available was 640 KB to play around, leaving aside MEMMAX.
Nowadays the only reason many embedded developers keep using C is religous.
The said library is a bit farther away from the C that is widely available. It relies on C23 features, GNU statement expression, GNU nested function, sanitizer runtimes, VLA types and a very niche pattern of sizeof executing its statement-expression argument; only platforms that provide latest GCC/Clang would be able to use this.
It is, but the bar of what's considered too 'clever' in embedded/firmware is usually lower than this. In fact, even the ternary conditional operator is too much.
Definitely. I still don't think you should swim against the stream. Just bite the bullet and write idiomatic C. The people who will have to debug your code in the future will thank you.
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.
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
> with the exception that the result can't be returned in a register (a problem which will go away if the function is inlined)
It's still a damned shame. Same for not being able to pass optional/unique_ptr/etc in a register.
We really need a trivially_relocatable attribute.
Proving the point that better type system and abstractions don't necessarly produce bad Assembly, and if constexpr is used, there won't be anything on the final executable other than the actual value.
https://gcc.godbolt.org/z/31o75W5xx
https://gcc.godbolt.org/z/av6a43WeY
Yeah it a amazing a far C++ has come, soon it will be almost as good as C.
In this instance C++ is far ahead of C, because what you want for maybe<> is typestate, and that's only available in C++ because it's wedded to member functions. See https://awesomekling.github.io/Catching-use-after-move-bugs-... or similar
Sure.
Except that it is much more safer to use the type system than pre-processor glue based on text replacements, with more interesting error messages than templates.
Is this because std::optional isn't trivially constructible?
Destructible. Opportunistically making it trivially destructible does the trick.
> 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?
In standard C yes. But any decent C compiler will offer stronger guarantees than the minimum that the standard requires, and presumably the "null sanitizer" they're referring to is one of them.
As usual, the problem is not what they have been offering for the last decades in tooling, rather what developers actually make use of.
Unfortunely many keep needing education on such matters.
Maybe, but it is defined for GCC:
> You can store a null pointer in any lvalue whose data type is a pointer type. [0]
Though, I would expect a complaint from clang, and clang-tidy.
[0] https://www.gnu.org/software/c-intro-and-ref/manual/html_nod...
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.
Quite. There's standard POSIX behaviour for this. Divide by zero and execution continues, safely, in your SIGFPE exception handler.
You don’t always get to choose your language. Especially in the embedded/firmware area of software development, C is the most widely available option, if not the only option besides ASM shrugs
Unless you are talking about PIC and similar CPUs, there is hardly a modern 16 bit CPU that doesn't have a C++ compiler available as well, assuming that we still consider 16 bit modern for whatever reason.
Heck I learned to program in C++, back when DR-DOS 5 was the latest version, and all I had available was 640 KB to play around, leaving aside MEMMAX.
Nowadays the only reason many embedded developers keep using C is religous.
The said library is a bit farther away from the C that is widely available. It relies on C23 features, GNU statement expression, GNU nested function, sanitizer runtimes, VLA types and a very niche pattern of sizeof executing its statement-expression argument; only platforms that provide latest GCC/Clang would be able to use this.
It is, but the bar of what's considered too 'clever' in embedded/firmware is usually lower than this. In fact, even the ternary conditional operator is too much.
Definitely. I still don't think you should swim against the stream. Just bite the bullet and write idiomatic C. The people who will have to debug your code in the future will thank you.