On 12/02/2016 12:56, Emil Dotchevski wrote:
Perhaps I'm biased by mostly developing on Windows+MSVC, but since that implements C++ exceptions by raising OS exceptions, and OS exceptions can be caught and processed just like C++ exceptions, I don't see any distinction between the two. (Though I'm aware that the OS exception handling mechanism is much more broken on non-Windows.)
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. There are some good things about this, as it makes it easier to recover a stack trace from a thrown exception -- though the corollary bad thing is that exceptions are also more expensive to throw. (Although there *is* an option which decides how aggressively it inserts the plumbing to catch OS exceptions, and leaving that off can improve performance at the cost of reducing the places that you can catch them.)
The only reason that shared_ptr::operator* does not throw is that the class author decided that this is likely a hot path and the calling code has *probably* already checked for null, so it is more *efficient* to omit the check entirely (and cause undefined behavior if called in violation of that assumption).
He can speak for himself, but I bet that his motivation was to avoid overhead in the extremely common use case when the programmer *knows* that the shared_ptr isn't null. If I have a shared_ptr (that I didn't get from weak_ptr::lock), more often than not it would be a logic error for it to be null, so it would be dumb to check if it is null when dereferencing it.
Which is exactly what I said.
Absolutely not. Dereferencing a null pointer in C++ is undefined behavior, which is not at all the same as throwing exceptions or raising OS exceptions. When you throw an exception, the standard specifies exactly what is going to happen, but in the case of undefined behavior all bets are off. Maybe your program will crash, maybe it'll send a nasty email to your boss. :)
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, this is technically undefined behaviour at the language level, but it is not undefined behaviour at the platform level (though it may still be "defined but unintended behaviour"). And yes, platforms do exist that do not have that characteristic, and they do have C++ compilers, and in that environment you won't get a fault in that case, you will get defined-but-almost-certainly-incorrect behaviour. So truly portable applications cannot *rely* on getting a fault, but there is a decent chance that they will experience it at some point nevertheless. You're taking this out of context, though; it was an aside only peripherally related to the main point.