• C++ exceptions are broken.

    From Mr Flibble@21:1/5 to All on Tue Mar 8 06:31:12 2016
    XPost: comp.lang.c++

    C++ exceptions are broken.

    As it currently stands a more serious std::logic_error exception can be downgraded into a less serious std::runtime_error exception if an
    exception is thrown whilst evaluating the throw expression. This is a nonsense.

    Fix: if an exception is thrown whilst evaluating a throw expression then std::terminate() is called.

    /Flibble


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James K. Lowden@21:1/5 to Mr Flibble on Wed Mar 9 08:25:52 2016
    XPost: comp.lang.c++

    On Tue, 8 Mar 2016 06:31:12 CST
    Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> wrote:

    As it currently stands a more serious std::logic_error exception can
    be downgraded into a less serious std::runtime_error exception if an exception is thrown whilst evaluating the throw expression.

    Could you be more specific, please? logic_error is mentioned in my
    copy of the C++ only in section 19.2.1 (per the index), and I don't
    find any mention of "downgrading". I also don't understand how it
    *could* happen, since the compiler generates exception-handling
    instructions, and the language per se doesn't define logic_error.

    Why do you say logic_error is "more serious" than runtime_error?
    Semantically that's not true, insofar as seriousness is not defined
    by the library. I guess you mean that -- assuming they're used as
    intended -- a logic error could have been avoided by the programmer,
    whereas a runtime error could not. Depending on the situation, though,
    either one can leave the user high and dry.

    --jkl


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?ISO-8859-1?Q?Elias_Salom=E3o_Helo@21:1/5 to All on Sat Mar 12 06:28:15 2016
    Why do you say logic_error is "more serious" than runtime_error?
    Semantically that's not true, insofar as seriousness is not defined
    by the library. I guess you mean that -- assuming they're used as
    intended -- a logic error could have been avoided by the programmer,
    whereas a runtime error could not. Depending on the situation,
    though,
    either one can leave the user high and dry.

    I agree that there is a semantic problem in saying that a logic error is
    more serious. But still, having a logic_error exception turned into a runtime_error exception seems wrong to me. However, it sounds like one
    should actually not write throw expressions that can throw another
    exception. This is what should be considered bad practice, IMO.

    The solution? Write simple throw expressions that cannot themselves
    throw an exception. Am I right, wrong, or is this impossible altogether?

    Best,
    Elias.


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mr Flibble@21:1/5 to James K. Lowden on Sat Mar 12 14:46:06 2016
    XPost: comp.lang.c++

    On 09/03/2016 14:25, James K. Lowden wrote:

    On Tue, 8 Mar 2016 06:31:12 CST
    Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> wrote:

    As it currently stands a more serious std::logic_error exception can
    be downgraded into a less serious std::runtime_error exception if an
    exception is thrown whilst evaluating the throw expression.

    Could you be more specific, please? logic_error is mentioned in my
    copy of the C++ only in section 19.2.1 (per the index), and I don't
    find any mention of "downgrading". I also don't understand how it
    *could* happen, since the compiler generates exception-handling
    instructions, and the language per se doesn't define logic_error.

    Typically when constructing an exception derived from std::logic_error a

    std::string object is created for the exception message which can cause std::bad_alloc (a std::runtime_error exception) to be thrown replacing
    the originally intended exception.


    Why do you say logic_error is "more serious" than runtime_error?
    Semantically that's not true, insofar as seriousness is not defined
    by the library. I guess you mean that -- assuming they're used as
    intended -- a logic error could have been avoided by the programmer,
    whereas a runtime error could not. Depending on the situation,
    though,
    either one can leave the user high and dry.

    In general std::logic_error is more serious then std::runtime_error
    because you can often recover from a std::runtime_error but a
    std::logic_error exception is often a sign that something is seriously
    screwed and the only safe course of action is to terminate the process.
    I treat std::logic_error based exceptions as fatal conditions because
    of this.

    /Flibble


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James K. Lowden@21:1/5 to Mr Flibble on Sun Mar 13 15:55:36 2016
    XPost: comp.lang.c++

    On Sat, 12 Mar 2016 14:46:06 CST
    Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> wrote:

    I also don't understand how it *could* happen, since the compiler
    generates exception-handling instructions, and the language per se
    doesn't define logic_error.

    Typically when constructing an exception derived from
    std::logic_error a std::string object is created for the exception
    message which can cause std::bad_alloc (a std::runtime_error
    exception) to be thrown replacing the originally intended exception.

    Oh, so you mean that the programmer may do something in handling the
    exception to convert logic_error to runtime_error. Sure.

    The programmer also has control over that. If it's important to pass logic_error up the stack unmolested, do not allocate any objects in the handler, or wrap that logic in its own try block. I've heard that in
    some shops it's standard practice to use only static strings in
    handlers to avoid the situation you describe.

    From my point of view, if std::string triggers bad_alloc, you're hip
    deep in alligators because your heap is corrupted. Likely is the
    logic_error is itself spurious, a knock-on effect of your pointers
    spending their spring break in Fort Lauderdale. So, yeah, grap
    __FILE__ and __LINE__, and head for the exit as soon as possible.

    --jkl


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Hergen Lehmann@21:1/5 to All on Sat Mar 12 16:50:46 2016
    XPost: comp.lang.c++

    Am 12.03.2016 um 21:46 schrieb Mr Flibble:

    In general std::logic_error is more serious then std::runtime_error
    because you can often recover from a std::runtime_error but a std::logic_error exception is often a sign that something is seriously screwed and the only safe course of action is to terminate the
    process.

    I don't see any basis for that assumption.

    std::logic_error includes stuff like std::domain_error (which is not
    even used by the STL) or std::invalid_argument, which might be some
    completely harmless rejection of input data.
    On the other hand, std::runtime_error includes std::system_error, which
    might be quite hazardous depending on which system operation did fail.

    Hergen


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gareth Owen@21:1/5 to Mr Flibble on Tue Mar 15 08:44:44 2016
    XPost: comp.lang.c++

    Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> writes:

    std::string object is created for the exception message which can
    cause std::bad_alloc (a std::runtime_error exception) to be thrown
    replacing the originally intended exception.

    std::bad_alloc is not a runtime_error (needing a string constructor
    would be particularly idiotic for bad_alloc), but the point still holds.


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gareth Owen@21:1/5 to James K. Lowden on Tue Mar 15 08:45:17 2016
    XPost: comp.lang.c++

    "James K. Lowden" <jklowden@speakeasy.net> writes:

    Oh, so you mean that the programmer may do something in handling the exception to convert logic_error to runtime_error. Sure.

    No, the problem is

    throw std::logic_error("I've made a terrible mistake");

    calls the constructor

    std::logic_error(const std::string&);

    which has to construct a string, which might throw std::bad_alloc


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bo Persson@21:1/5 to Gareth Owen on Tue Mar 15 12:22:07 2016
    XPost: comp.lang.c++

    On 2016-03-15 15:45, Gareth Owen wrote:

    "James K. Lowden" <jklowden@speakeasy.net> writes:

    Oh, so you mean that the programmer may do something in handling the
    exception to convert logic_error to runtime_error. Sure.

    No, the problem is

    throw std::logic_error("I've made a terrible mistake");

    calls the constructor

    std::logic_error(const std::string&);

    which has to construct a string, which might throw std::bad_alloc



    There is also a constructor

    explicit logic_error(const char*);

    which doesn't have to call a string constructor.



    Bo Persson


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Alf P. Steinbach@21:1/5 to Bo Persson on Thu Mar 17 06:43:54 2016
    XPost: comp.lang.c++

    On 15.03.2016 19:22, Bo Persson wrote:

    There is also a constructor

    explicit logic_error(const char*);

    which doesn't have to call a string constructor.

    Oh, it has to allocate memory dynamically for the string if it exceeds
    some buffer size, because there is no requirement that the actual
    argument points to a string that will outlive the exception object.

    Most probably any particular implementation delegates the dynamic
    allocation job to `std::string`.

    However, considering that `what` is virtual function that produces a
    `char const*`, it's not difficult at all to create a derived exception
    class that doesn't do dynamic allocation.


    Cheers!,

    - Alf


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paavo Helde@21:1/5 to Bo Persson on Thu Mar 17 06:43:44 2016
    XPost: comp.lang.c++

    On 15.03.2016 20:22, Bo Persson wrote:

    On 2016-03-15 15:45, Gareth Owen wrote:

    "James K. Lowden" <jklowden@speakeasy.net> writes:

    Oh, so you mean that the programmer may do something in handling the
    exception to convert logic_error to runtime_error. Sure.

    No, the problem is

    throw std::logic_error("I've made a terrible mistake");

    calls the constructor

    std::logic_error(const std::string&);

    which has to construct a string, which might throw std::bad_alloc



    There is also a constructor

    explicit logic_error(const char*);

    which doesn't have to call a string constructor.

    The const char* argument is not guaranteed to be a static string so it
    still needs to be copied over, allocating an arbitrarily large amount of memory.

    The standard also says:

    logic_error(const char* what_arg);
    4 Effects: Constructs an object of class logic_error.
    5 Postcondition: strcmp(what(), what_arg) == 0.

    The post-condition makes it illegal to ignore or truncate the argument
    string, thus leaving an exception as the only conforming way to cope
    with memory exhaustion.

    It is interesting to note that MSVC implementation for example appears
    to be not standard conforming and just ignores the argument if the
    memory allocation fails.




    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)