4 ms·
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 wil
by nly 1y ago
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 https://gcc.godbolt.org/z/vfzK9Toz4
- uecker 1y agoYeah it a amazing a far C++ has come, soon it will be almost as good as C.
- JonChesterfield 1y agoIn 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-with-Clang-consumed-annotations/ https://awesomekling.github.io/Catching-use-after-move-bugs-... or similar
- uecker 1y agoSure.
- deleted 1y ago[deleted]
- pjmlp 1y agoExcept 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.
- uecker 1y agoI don't see how it safer. I think this is just a random claim C++ people like to make without any evidence. In terms of error message, the problem is that C++ often can not produce them because due to overloading it is entirely unclear to the compiler what the intention of the code actually way. A macro-based solution also does not have ideal error message, but I do not think it is worse than C++.
- pjmlp 1y agoIt isn't a random claim, is based on years of experience fixing pre-processing code gone wrong, because whoever wrote it in first place forgotten that it is nothing more than text expansion, and then someone else completly unaware that it is a macro, ends up giving a bad set of parameters.
- uecker 1y agoI spent also countless amount of hours fixing template code, so no I do not let your anecdotes count. There is certainly a lot of problematic macro code in C, but I do not think it is worse than C++ templates, and one can also write robust macros.
- pjmlp 1y agoOne can also write robust template code, if that is the reasoning we're going for, enable_if, static_assert and concepts have been available for a couple of years now. At least that is something we can agree on, C and C++ are both languages where developers could write robust code, and the large majority seldom does it.
- uecker 1y agoI can agree with this. The difference is that C++ approach is to solve problems with features people need to understand while C solves problems by only providing basic building blocks and expects people to use them correctly. In both cases it needs expertise to do this. But Rust also has this problem.
- wahern 1y agoIs this because std::optional isn't trivially constructible?
- pwdisswordfishz 1y agoDestructible. Opportunistically making it trivially destructible does the trick.
- pjmlp 1y agoProving 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/31o75W5xx https://gcc.godbolt.org/z/av6a43WeY https://gcc.godbolt.org/z/av6a43WeY
- uecker 1y agoYou do not need constexpr, just remove the "volatile" which I put into my example only to prevent the optimizer from specializing it: https://godbolt.org/z/fs8q3sdxK https://godbolt.org/z/fs8q3sdxK But what matters is run-time behavior for any input. And sorry, C++'s complexity still has the effect that the code is terrible: https://godbolt.org/z/vWfjjf8rP https://godbolt.org/z/vWfjjf8rP In C, the compiler can remove all error paths: https://godbolt.org/z/GGMcc6bxv https://godbolt.org/z/GGMcc6bxv
- nly 1y agoNot sure what you're talking about here. The cruft the assembly is because you enabled UBSAN. If you disable UBSAN then the exception throwing code paths go away.
- uecker 1y agoThe point is that the error code paths should go avoid even with UBSAN because they are dead, but the optimizer is not able to see this anymore in C++.
- aw1621107 1y ago> But what matters is run-time behavior for any input. And sorry, C++'s complexity still has the effect that the code is terrible: https://godbolt.org/z/vWfjjf8rP https://godbolt.org/z/vWfjjf8rP > In C, the compiler can remove all error paths: https://godbolt.org/z/GGMcc6bxv https://godbolt.org/z/GGMcc6bxv For what it's worth, if you actually use the same flags for the C++ example (in particular, -fsanitize-trap) the C++ compilers improve quite a bit, with Clang getting fairly close to the GCC C output (https://godbolt.org/z/M3z5EaGKj https://godbolt.org/z/M3z5EaGKj ; note that GCC doesn't seem to eliminate the std::optional::value() check unless you use -O3). But perhaps more interestingly, if you make a simplified std::optional that still uses C++-specific features both Clang and GCC produce output that is very close to that from C/GCC: https://godbolt.org/z/PhEW7eT8x https://godbolt.org/z/PhEW7eT8x Removing I/O-related stuff makes this clearer: C: https://godbolt.org/z/e71s9E63f https://godbolt.org/z/e71s9E63f C++: https://godbolt.org/z/YnhdxYxY4 https://godbolt.org/z/YnhdxYxY4 (Clang seems unable to eliminate the UBSan overflow check for some reason?) Does make me wonder what exactly it is about std::optional that confuses the optimizers, and whether a similarly complex C maybe implementation can suffer from the same issues that std::optional appears to.
- account42 1y ago> 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.