Hi Thiago, On Thursday August 2 2012, Thiago Macieira wrote: > The benefits are: > - callers do not need to emit exception handlers around such functions > - the compiler may assume that no exception unexpectedly happens inside > that function body, foregoing exception handlers inside it as well.
AFAIU, the compiler needs to make sure that std::terminate is called if an unexpected exception is thrown, which would require the equivalent of a function-try-catch block where the catch block calls std::terminate(). Do you have a reference? > The first behaviour is present with a C++03's empty exception specification > (i.e., throw() in the function declaration), AFAIU, that's only true for MSVC, and counter to what C++03 actually mandated. > but the second behaviour is > new in C++11. In the previous standard, the compiler was forced to emit > exception code for the case when exceptions did happen even when they > shouldn't. For that reason, the C++03 exception specification is > deprecated. Ok, here I'm with you again. Btw, I've done some very rough tests: What I set out to check was whether calling non-noexcept functions from noexcept ones incurs a penalty for the std::terminate call that is required if a noexcept function would leak an exception (it can't, it must invoke std::terminate() instead, and the GCC compilate works as expected in that respect, when I make foo() below throw) vs. if the compiler can prove that all operations are noexcept. What I found was that a declaration int foo() noexcept; vs. int foo(); doesn't influence the assembly at all (expected, the exception must be swallowed inside foo(), not, as with throw() by the caller of foo()). But int foo(); int bar() noexcept { const int f = foo(); return 2*f;} seems to introduce a new entry in the gcc_except_table (that's expected, too. bar() needs to be prepared for foo() to throw and call std::terminate() in response) whereas int foo() noexcept; int bar() noexcept { const int f = foo(); return 2*f; } does not (also expected, as the compile can now prove that the body of bar() can't throw; the responsibility of preventing exceptions from exiting foo() is now with foo()'s implementation). The function itself is unchanged, though. I don't know enough compiler internals to properly interpret this result :) In a similar test, int foo(); int bar() noexcept { const int f = foo(); return 2*f; } also adds an entry to the exception table, compared to int foo(); int bar() { const int f = foo(); return 2*f; } which doesn't. What's more interesting is that I get with -m64 -O2 and no -g an .o size difference of 1360 bytes for the second vs. 1576 for the first variant. This size difference is much bigger than I would have expected from the .s-file diff. For comparision, the size for both bar() and foo() noexcept is also 1360. If there really is a 200 byte overhead per nonexcept function calling non-noexcept functions, we'd need to avoid marking functions noexcept that, say, Q_ASSERT(), e.g., even though we could probably live with the std::terminate that's called if Q_ASSERT() throws (at that point, it's clear that the assertion failed, if not from the resulting backtrace) :) Even if it isn't a full 200 bytes overhead, we should make qt_assert() noexcept before putting it on, say, QMutex::lock() which calls it. Thanks, Marc -- Marc Mutz <marc.m...@kdab.com> | Senior Software Engineer KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090 KDAB - Qt Experts - Platform-Independent Software Solutions _______________________________________________ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development