|
Boost : |
Subject: Re: [boost] expected/result/etc
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2016-02-11 21:36:34
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.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk