4 ms·
> In C++, use -fno-exceptions if your code doesn't use exceptions. > In C++, use -fno-rtti if your code doesn't use RTTI (run-time type identification) or dyna
by wyldfire 3y ago
> In C++, use -fno-exceptions if your code doesn't use exceptions.
> In C++, use -fno-rtti if your code doesn't use RTTI (run-time type identification) or dynamic_cast.
Note that "your code" here generally must encompass "your code" and all of your C++ archives/shared object dependencies (and their dependencies).
- lldb 3y agoYou can usually compile each library independently with/without exceptions and rtti and it works as expected.
- mhh__ 3y agoWorks as expected or silently fails to destruct things properly during unwinding?
- mort96 3y agoHaven't tried, but it almost certainly fails in fun and unexpected ways I'd guess. Code which happens to be in your dependencies' source files probably works as expected, code which happens to be in your dependencies' source files will be compiled without RTTI/exceptions and therefore possibly break in fun and interesting ways. And I wonder what happens if your code creates a class which inherits from a base class defined in a library and that library expects anything which inherits from that base class to have runtime type info.
- Kranar 3y agoNothing breaks in fun or interesting ways. All that happens is std::terminate is called.
- mort96 3y agoEven when a template or inline function depends on RTTI but is called in a source file compiled with -fno-rtti? And if a template or inline function depends on catching an exception, you're right that your app unexpectedly crashing due to std::terminate isn't "fun or interesting" but it's not really great either.
- Kranar 3y agoTemplates and RTTI do not have anything to do with each other. An inline function that depends on RTTI will fail to compile when -fno-rtti is enabled. There is also nothing unexpected about an application immediately terminating due to an exception. That's the most expected outcome in an application that has made an explicit choice to not handle exceptions and is what happens in any application that does not have a try/catch handler.
- mort96 3y agoTemplates and inline functions are relevant because they're in headers and therefore compiled as part of your project's translation units. So if a function from a library depends on RTTI, and it's compiled as part of your project's translation units with -fno-rtti, something will break (or maybe you'll have an ODR violation). > There is also nothing unexpected about an application immediately terminating due to an exception. That's the most expected outcome in an application that has made an explicit choice to not handle exceptions and is what happens in any application that does not have a try/catch handler. If I call a function from a library, and that library function depends on catching and handling exceptions (maybe it uses a stdlib function which throws, such as vector::at), it's unexpected that my application crashes due to that exception. Yet, if that library function happens to be in a header, calling it will crash my program (or, again, you have an ODR violation and anything could happen).
- Kranar 3y agoYou get a compiler error.
- Calavar 3y agoIt's similar to slapping noexcept on every function in a compilation unit. Unwinding will still happen as usual in compilation units where exceptions were enabled. When a function in an -fno-exceptions compilation unit calls a function that might throw exceptions, the compiler inserts an exception handler that calls std::terminate. std::terminate won't call any destructors further up the chain, but if all you're doing in destructors is deallocating memory and releasing handles to system resources, this shouldn't matter.
- inetknght 3y ago> if all you're doing in destructors is deallocating memory and releasing handles to system resources, this shouldn't matter. Note that closing system resources is often abortive. On the other hand, object destructors might wait for a flush.
- wyldfire 3y ago> if all you're doing in destructors is deallocating memory and releasing handles to system resources, this shouldn't matter. That "if" is doing some heavy lifting. C++ places a lot of stock in RAII, so failing to call destructors could cause lots of interesting failure modes. I don't think it's fair to dismiss this fundamental part of the language so easily.
- Calavar 3y agoIf the user kills your program with Ctrl-C, you don't have any destructor guarantees. If your program is killed by the OS because the user logged off or powered down their machine, you don't have any destructor guarantees. If your program fails an assertion, you don't have any destructor guarantees. If your program segfaults, you don't have any destructor guarantees. This really isn't that exotic of a scenario. My personal opinion is that using RAII to do anything that you wouldn't trust the OS do for you in the event of an early termination is setting yourself up for disaster.
- hamilyon2 3y agoDo you have a newsletter that I can sign up for?
- jcelerier 3y ago-fno-exceptions does not disable unwinding support afaik, for this you need -fno-unwind-tables / -fno-asynchronous-unwind-tables ; if I'm not mistaken unwind table generation is enabled even in C with GCC and clang
- pjmlp 3y agoIt works by chance more than anything.
- lelanthran 3y agoAgreed, but how certain can you be that the program generates no exceptions? Simply instantiating a pointer to class using new uses exceptions. Without exceptions all constructors that fail turn into undefined behaviour. The caller will never know that the instance they are using is filled with random bytes.
- ridiculous_fish 3y agoI'm not sure that a failing constructor is UB under -fno-execptions. The libstdc++ manual suggests that these will instead abort: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html#intro.using.exception.no https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_except...
- zabzonk 3y ago> I'm not sure that a failing constructor is UB under -fno-execptions the c++ standard does not allow for disabling exceptions, so at best this would be implementation-dependent behaviour, at worst UB. in other words, using -fno-execptions, and similar on other compilers, raises compatibility problems.
- mort96 3y agoYou're right, the C++ standard does not allow for disabling exceptions. So C++ with exceptions disabled is not a language described by the standard. We instead have to look at the documentation of this "C++ with exceptions disabled" language. And this "C++ with exceptions disabled" language defines that exceptions terminate the program. There is no UB anywhere here, everything is well-defined. You're right again though that there are compatibility problems, you could hypothetically use a compiler whose '-fno-exceptions' option actually defines throwing exceptions to be UB. No compiler would do that since it's obviously insane, but it is a possible alternate "C++ with exceptions disabled" language. Make sure to not use such compilers. And it's probably a good idea to keep your code valid C++ anyways, meaning a standard C++ compiler will terminate the program due to an uncaught exception while GCC and Clang with -fno-exceptions will terminate the program by calling abort(). This way, GCC and Clang's -fno-exceptions behavior is just an optimization for when compiling on those compilers.