On 12/02/2016 14:27, Emil Dotchevski wrote:
It's criminal that MSVC can translate OS exceptions into C++ exceptions. :) It's not that it's broken on other OSes, other compilers don't do this because it's wrong. I do not recommend turning that MSVC option on.
It's not an option. That's just what it does.
Not true, it's an option. They call it "structural exception handling".
As I mentioned, as far as I am aware that just disables the ability to catch such exceptions (in part, by only inserting the logic for unwinding in places that it expects C++ exceptions). I don't think it stops the compiler transporting exceptions that way. I could be wrong about that though.
On pretty much any platform with an MPU the memory around address 0 is left unmapped precisely such that such accesses generate an OS fault.
Yes, but there is no requirement for the program to be able to unwind the stack and call destructors, as it does when throwing C++ exceptions. It's makes no sense to expect a program to be able to recover from undefined behavior because at that point the state of the program is undefined, by definition.
Except it's not. If a particular platform generates a bus error on access to protected memory (including null memory), it typically further guarantees how to recover from such a hardware exception (typically by adjusting the return address), and indeed all OSes do so in some fashion or another. This is not really any different from platforms like Java or .NET that throw a NullReferenceException or other AccessViolationException or whatever in this case. (Except that those languages typically make it slightly harder to stomp completely roughshod over memory.) On Windows that translates to a structured exception which is thread-specific and (if async exceptions are enabled) can be caught, logged, and recovered from in some sane fashion *if* the application can know what is sane -- but especially in state-free applications (eg. web servers) that is also well defined, usually by abandoning the operation and logging or returning an error. On POSIX that translates to a signal that is not thread-specific and can't really be dealt with in any sane way except terminating the entire process. While terminating the process is *often* the best reaction to this sort of failure, it is not exclusively so, and POSIX is dumb for not permitting the application the choice. (Admittedly Windows is also dumb for permitting the application the choice, since there are a lot of people who do completely the wrong thing. You can't really argue that either way is the best.) Again, though, this is a platform-level definition and not a language-level definition. C++ itself does not define what happens when you access memory out of bounds -- the platform does, and if you're writing portable code that's platform-agnostic then you cannot rely on the behaviour of a particular platform, obviously. But if you aren't, then you can.