3 ms·
The compiler can tell about the immediate function, but not any functions it calls. If a function marked noexcept calls a function that throws an exception, th
by compiler-guy 2y ago
The compiler can tell about the immediate function, but not any functions it calls.
If a function marked noexcept calls a function that throws an exception, then the program is terminated with an uncaught exception. A called function can throw through a non-noexcept function to a higher-level exception handler no problem.
So in order to avoid changing the semantics of the function, the compiler would have to be able to determine that that transitive closure of called functions dynamically don't throw, and that problem is undecidable, even assuming the requirement that "the compiler can see the source of all those functions" is somehow met, which it won't be.
- terrymah 2y agoNo, we compile in bottom up order, starting with leaf functions, and collecting information about functions as we go. So "not throwing" sort of trickles up when possible to a certain degree. In LTCG (MSVC)/O3 (GCC/Clang) there are prepasses over the entire callgraph to collect this order
- deleted 2y ago[deleted]
- deleted 2y ago[deleted]
- deleted 2y ago[deleted]
- deleted 2y ago[deleted]
- compiler-guy 2y agoYes of course. Sometimes the compiler can tell. But the original question feels to me more like “Shouldn't the compiler deduce restrict for you?”
- tsimionescu 2y ago> A called function can throw through a non-noexcept function to a higher-level exception handler no problem. This is exactly the problem. To have made this a useful feature, it should have been more restrictive: a noexcept function should not have been allowed to call any function or operator or lambda that is not marked noexcept. Some extra syntax to allow function templates to be made "conditionally noexcept" would have been necessary, but overall the feature would have had a real use and real power to help make code safer, and more performant. Java has the first part down, for the class of checked exceptions: a function that doesn't throw can't call functions that do (except in try/catch blocks, but that's largely irrelevant). The annoyances come because of the missing second part - the ability to make a generic function that throws for some type parameters, but doesn't for others.
- cesarb 2y ago> Java has the first part down, for the class of checked exceptions: a function that doesn't throw can't call functions that do (except in try/catch blocks, but that's largely irrelevant). That's not actually true, it's possible to do "sneaky throws" (https://www.baeldung.com/java-sneaky-throws https://www.baeldung.com/java-sneaky-throws) of a checked exception from a method which isn't declared to throw that checked exception. The classic example is Class.newInstance(), which propagates any exception from the called constructor. Other ways are calling code from JVM languages other than Java, which do not have the same "checked exception" concept (like Kotlin: see https://kotlinlang.org/docs/exceptions.html https://kotlinlang.org/docs/exceptions.html and https://kotlinlang.org/docs/java-to-kotlin-interop.html#checked-exceptions https://kotlinlang.org/docs/java-to-kotlin-interop.html#chec...), generics trickery to confuse the compiler, and manually creating JVM bytecode.
- tsimionescu 2y agoSure, but that's essentially the same as using explicit jumps through raw assembly instructions to go around C++'s destructor guarantees. That is, when your Java process runs non-Java code, of course this can defeat certain Java guarantees. No programming language can make promises for semantics of external code like this.