So the advantages to embarking on a "mark everything that can be no except as no except" windmill charge are two fold: 1 - The compiler might be able to do a little bit better optimization. 2 - It'll force me think even harder about all my code than I already have. The disadvantages are 1. My code will then be littered with a bunch of noexcept clauses that'll really tempt me to redo a bunch of really hard "I'd better make sure I'm right about that" thinking every time I see them. 2 - If I turn out to be wrong in some number cases, that's that many places where my program will crash. Hmm.
I wish the ctte had decided that the conditional noexcept specifier was called "noexcept_if" and the noexcept expression was "is_noexcept". That way instead of one keyword doing three things, there'd be three keywords: "noexcept" to declare that a function should not throw, "noexcept_if" to declare a function will conditionally not throw, and "is_noexcept" to determine if an expression can throw. This also cleans up the "noexcept(noexcept(...))" weirdness -- instead you'd have "noexcept_if(is_noexcept(...))". Maybe even drop some of the parens to just have "noexcept_if is_noexcept (...)"
OMG. The exactly previous video I watched was discussing misuse of std::map::operator[] as the most frequent source of production level bugs at Facebook (Louis Brnady: CppCon 2017: Curiously Recurring C++ Bugs). I am wondering how long will it take to our gurus to figure out that programming is a mass profession, and that barely 1% of this mass are capable of writing exception safe code without compiler(or static-analyzer) support.
Its because 99% of the programmers at facebook are php programmers, and thats the way you use maps in php. They never use the count function first to check if it exists, because php doesn't give a crap but C++ is a different beast altogether.
Robust exception handling (cleaning up resources on all execution paths, undoing all visible changes to global state) is notoriously hard. It's something experts get wrong.
so as soon as you compare the name returned from type_info - what else are you going to do with it, use it as an already-hashed value in a set or map? - then you have to call *strlen()* and you might as well have returned a *string_view* in the first place. This gets more true the more times you compare the name with something. RTTI should ideally deal in more modern idioms.
There's an interesting talk that occurred on the same day about zero-cost exception handling here on YT ruclips.net/video/_Ivd3qzgT7U/видео.html . Also, another talk the next february by Peter Edwards where he explains with great details how to implement zero-cost exception handling. I think that's the right direction to go rather than relying on the developers to fully grasp the implications of noexcept. It's here on YT: ruclips.net/video/XpRL7exdFL8/видео.html Also, what's the difference between "noexcept" versus "throw()", and "noexcept(false)" versus "throw(...)"? To avoid double negation, could the language have evolved by making "throw()" accept a boolean value? I also can't help but wonder if a compiler could look at function definitions and emit a hint message helping the user determine that he can add a noexcept to the signature. Maybe also some syntax would be welcome to explicitly ask the compiler to choose the right noexcept value when the function definition is "inlined".
Making a function noexcept gives no performance improvement (as Jason admits), but it commits all specialised functions in derived classes to also be noexcept. "If a virtual function is non-throwing, all declarations, including the definition, of every overrider must be non-throwing as well, unless the overrider is defined as deleted". Seems like a bad idea to me!
Jason always delivers. Great talk!
So the advantages to embarking on a "mark everything that can be no except as no except" windmill charge are two fold:
1 - The compiler might be able to do a little bit better optimization.
2 - It'll force me think even harder about all my code than I already have.
The disadvantages are
1. My code will then be littered with a bunch of noexcept clauses that'll really tempt me to redo a bunch of really hard "I'd better make sure I'm right about that" thinking every time I see them.
2 - If I turn out to be wrong in some number cases, that's that many places where my program will crash.
Hmm.
I wish the ctte had decided that the conditional noexcept specifier was called "noexcept_if" and the noexcept expression was "is_noexcept".
That way instead of one keyword doing three things, there'd be three keywords: "noexcept" to declare that a function should not throw, "noexcept_if" to declare a function will conditionally not throw, and "is_noexcept" to determine if an expression can throw.
This also cleans up the "noexcept(noexcept(...))" weirdness -- instead you'd have "noexcept_if(is_noexcept(...))".
Maybe even drop some of the parens to just have "noexcept_if is_noexcept (...)"
OMG. The exactly previous video I watched was discussing misuse of std::map::operator[] as the most frequent source of production level bugs at Facebook (Louis Brnady: CppCon 2017: Curiously Recurring C++ Bugs). I am wondering how long will it take to our gurus to figure out that programming is a mass profession, and that barely 1% of this mass are capable of writing exception safe code without compiler(or static-analyzer) support.
So, what is your assertion then?
Its because 99% of the programmers at facebook are php programmers, and thats the way you use maps in php. They never use the count function first to check if it exists, because php doesn't give a crap but C++ is a different beast altogether.
Robust exception handling (cleaning up resources on all execution paths, undoing all visible changes to global state) is notoriously hard. It's something experts get wrong.
31:30 such noexcept doesnt check if type T returned by callable is nothrow convertible to bool.
so as soon as you compare the name returned from type_info - what else are you going to do with it, use it as an already-hashed value in a set or map? - then you have to call *strlen()* and you might as well have returned a *string_view* in the first place. This gets more true the more times you compare the name with something. RTTI should ideally deal in more modern idioms.
I didn't get why it's hard to place a breakpoint on std::terminate to see the call stack. Most of the debuggers should have this functionality.
Its not about breakpoints but about calling destructors for objects created before noexcept violation happened.
There's an interesting talk that occurred on the same day about zero-cost exception handling here on YT ruclips.net/video/_Ivd3qzgT7U/видео.html . Also, another talk the next february by Peter Edwards where he explains with great details how to implement zero-cost exception handling. I think that's the right direction to go rather than relying on the developers to fully grasp the implications of noexcept. It's here on YT: ruclips.net/video/XpRL7exdFL8/видео.html
Also, what's the difference between "noexcept" versus "throw()", and "noexcept(false)" versus "throw(...)"? To avoid double negation, could the language have evolved by making "throw()" accept a boolean value? I also can't help but wonder if a compiler could look at function definitions and emit a hint message helping the user determine that he can add a noexcept to the signature. Maybe also some syntax would be welcome to explicitly ask the compiler to choose the right noexcept value when the function definition is "inlined".
You need to add noexcept(false) on destructors that are allowed to throw - and yes, there are reasons for that
as far as I know, "man errno" states that errno is thread safe, so exception on that regard is still useless
Jason Tunner well delivered, Great JobTalk.!
Making a function noexcept gives no performance improvement (as Jason admits), but it commits all specialised functions in derived classes to also be noexcept. "If a virtual function is non-throwing, all declarations, including the definition, of every overrider must be non-throwing as well, unless the overrider is defined as deleted". Seems like a bad idea to me!
virtual function is an API
if api says function is noexcept, but derived code throws, it is fail of a contract