signal handling and (structured) exception handling

Discussion in 'C++' started by Peter, Oct 9, 2009.

  1. Peter

    Peter Guest

    I'm a little bit at loss, why the new C++ standard (C++0x) does not
    include something like Windows structured exception handling.
    I certainly prefer a C++ Exception to a signal, as the signal only
    gives you the choice to terminate the process or mess around with
    something as ugly as setjmp/longjmp.
    And such signals/exceptions can sometimes not be avoided, e.g. in case
    of the system runs out of disk space while writing into memory created
    by memory mapped io from a sparse file.

    Even in case of a null pointer access I would prefer to keep the
    application running to be able to terminate it correctly. In this case
    probably there is no need to try to execute the last verb again,
    because it will run into the same null pointer access -- but at least
    the destructors should work and the application can be terminated
    correctly.

    Another example is a floating point exception.
    With exception handling I could avoid having to secure the code
    against invalid inputs,
    which also slows it down.
     
    Peter, Oct 9, 2009
    #1
    1. Advertising

  2. Peter wrote:
    > I'm a little bit at loss, why the new C++ standard (C++0x) does not
    > include something like Windows structured exception handling.


    Why should it be included in the Standard (new or old) when any
    implementation is free to provide its own way of dealing with those?

    > I certainly prefer a C++ Exception to a signal, as the signal only
    > gives you the choice to terminate the process or mess around with
    > something as ugly as setjmp/longjmp.


    Signals aren't really normative, are they?

    > And such signals/exceptions can sometimes not be avoided, e.g. in case
    > of the system runs out of disk space while writing into memory created
    > by memory mapped io from a sparse file.
    >
    > Even in case of a null pointer access I would prefer to keep the
    > application running to be able to terminate it correctly.


    Access to null pointer has undefined behaviour. The implementation is
    free to define it. Some do. Some don't. There is no need to introduce
    limitations by specifying what should happen.

    > In this case
    > probably there is no need to try to execute the last verb again,
    > because it will run into the same null pointer access -- but at least
    > the destructors should work and the application can be terminated
    > correctly.


    Whatever. If you're using a sophisticated operating system that allows
    you to handle such a situation, be happy. You seem unhappy for some
    reason. Do you want your Windows application with all the SEH stuff be
    runable on MS-DOS? And you want the language to provide the means? I
    do not see this as reasonable.

    > Another example is a floating point exception.
    > With exception handling I could avoid having to secure the code
    > against invalid inputs,
    > which also slows it down.


    Slows it down? By how much? I've worked in systems that were set up to
    handle FP exceptions and invalid pointer access... If you want it done
    right, every damn function has to be littered with try/catch for those.
    It is much, MUCH, easier to make sure you never try to calculate a
    logarithm of a negative value or you never hang onto a dangling pointer.
    A test for greater than 0 is so much quicker than setting everything
    up for stack unwinding...

    But you don't have to listen to me. If you see how Microsoft Structured
    Exceptions can be brought into the language and implemented everywhere
    the C++ compilers can exist, do write it up. I am sure folks in
    comp.std.c++ will read your proposal with the same attention they give
    every proposal.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Oct 9, 2009
    #2
    1. Advertising

  3. On Oct 8, 6:05 pm, Victor Bazarov <> wrote:
    > Peter wrote:
    > > I'm a little bit at loss, why the new C++ standard (C++0x) does not
    > > include something like Windows structured exception handling.

    >
    > Why should it be included in the Standard (new or old) when any
    > implementation is free to provide its own way of dealing with those?
    >
    > > I certainly prefer a C++ Exception to a signal, as the signal only
    > > gives you the choice to terminate the process or mess around with
    > > something as ugly as setjmp/longjmp.

    >
    > Signals aren't really normative, are they?
    >


    Signals are normative. There is lots of informative left out of the
    normative (standard).

    > > And such signals/exceptions can sometimes not be avoided, e.g. in case
    > > of the system runs out of disk space while writing into memory created
    > > by memory mapped io from a sparse file.

    >
    > > Even in case of a null pointer access I would prefer to keep the
    > > application running to be able to terminate it correctly.

    >
    > Access to null pointer has undefined behaviour.  The implementation is
    > free to define it.  Some do.  Some don't.  There is no need to introduce
    > limitations by specifying what should happen.
    >
    >  > In this case
    >
    > > probably there is no need to try to execute the last verb again,
    > > because it will run into the same null pointer access -- but at least
    > > the destructors should work and the application can be terminated
    > > correctly.

    >
    > Whatever.  If you're using a sophisticated operating system that allows
    > you to handle such a situation, be happy.  You seem unhappy for some
    > reason.  Do you want your Windows application with all the SEH stuff be
    > runable on MS-DOS?  And you want the language to provide the means?  I
    > do not see this as reasonable.
    >
    > > Another example is a floating point exception.
    > > With exception handling I could avoid having to secure the code
    > > against invalid inputs,
    > > which also slows it down.

    >
    > Slows it down?  By how much?  I've worked in systems that were set up to
    > handle FP exceptions and invalid pointer access...  If you want it done
    > right, every damn function has to be littered with try/catch for those.
    >   It is much, MUCH, easier to make sure you never try to calculate a
    > logarithm of a negative value or you never hang onto a dangling pointer.
    >   A test for greater than 0 is so much quicker than setting everything
    > up for stack unwinding...
    >
    > But you don't have to listen to me.  If you see how Microsoft Structured
    > Exceptions can be brought into the language and implemented everywhere
    > the C++ compilers can exist, do write it up.  I am sure folks in
    > comp.std.c++ will read your proposal with the same attention they give
    > every proposal.
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    It seems reasonable as a pattern to encapsulate generic exception
    handling in the C++ towards that it is instrumentable generally.

    Here are some of my ideas from the other day about cwd: current
    working directory. When considering how to handle the exceptions
    generally, catch the signals and throw them back to the functions
    maybe having each function register itself as the signal handler, in
    the generic exception handling logic.

    Also I am thinking some about "generic return types" and also
    generifed return types in terms of considering what C++ can do for me.

    To truncate the file specifications might be great, with the automatic
    matching of the free input component.

    static cwd here

    put static functions on cwd, then use here for the file functions,
    file_system_point

    class cwd
    {
    std::string directory; // this is the current working directory
    directory
    }



    use the inline functions, anonymous functions, to, defer
    initialization of the carry-over variable

    if there's no initial match, it's set to zero

    here, the point is to collect several modes of the strings, basically
    having the modes saved in the static variables

    so, the path comes in, is it a delta off of the working directory, or
    absolute / rooted?

    basically for the path root, there is either the working directory as
    the root or the path contains its own root (which might include
    volume, host, etcetera, which would have static process events on
    events with those).

    So, I want to get the path, and compare it to the working directory.
    If it's relative the working directory, then truncate it's initial
    matching segments, the parameter, for later calls using the same
    initial segment.

    Then set up mode arrays, with this path construction and validation
    generally throughout with public APIs.

    So, the mode strings should be any number of matching initial segments
    and patterns.

    Then, among those are to be the collapse and the matching of the
    segments / strings.

    Make the path components, similar to the path segments, with getting
    out the names.

    So, to match the working directory, it's towards where the actual
    parameters can be reduced, until, they have to be assembled already to
    access the device or so, here relative to particular points they have
    more direct addressing which carries down to all the functions
    underneath, where for example there is a static main process working
    directory object that the static function members initialize to.

    Then, it is more about instrumenting the function with automatically
    recognizing its input types, memoizing its inputs, than it is about
    particularly the working directory as a process level point
    representing a local root for general purposes that has then those
    parameters being in a reduced form as they pass through the standard
    APIs.

    /*

    cwd, current working directory, helper

    */

    #include <unistd.h>

    int ret_getcwd(char* getcwd_, char* buf, size_t size)
    {

    // if it's a null pointer, there was an error

    // get errno, mutex on errno
    switch(errno)
    {
    case EINVAL: // The size argument is 0.
    // retry the function with a different size argument
    case ERANGE: // The size argument is greater than 0, but is smaller
    than the length of the pathname +1.
    case EACCES: // Read or search permission was denied for a component
    of the pathname.
    case ENOMEM: // Insufficient storage space is available
    }
    }

    class getcwd_ret_t
    {
    size_t m_buf_size = MAX_PATH; // restrict to expected with retry
    char* m_buf[m_buf_size];
    int m_errno;

    getcwd_ret_t(*void getcwd_= getcwd)
    : m_errno(0)
    {
    char* buf = getcwd_(m_buf, m_buf_size);
    // test here
    }

    bool retryable(int m_errno)
    {
    // the errno is set
    }

    // ret is either OK or not OK
    operator !()
    { // check also if m_buf is valid pointer, here is automatic
    return (m_buf != 0) || retryable(m_errno);
    }

    // ret is insertable in chaining functions
    operator char*(char*& c)
    {
    return c = m_buf;
    }

    operator=(void) // function pointer of same type as getcwd
    {
    // here install via templates
    }


    };

    #define getcwd() getcwd_ret_t ret =

    class cwd
    {
    std::string m_directory; // this is the current working directory
    directory

    public cwd()
    {
    size_t buf_size = MAX_PATH;
    char* buf[buf_size];

    getcwd(buf, buf_size); // build in ret
    m_directory(buf,buf_size); // construct better with size

    }

    static assign_to(const std::string& s); // sets the CWD for the
    function call, no,
    static assign_to(const char* s); // sets the CWD for the function
    call,

    static is_equal(const std::string& s); // sets the CWD for the
    function call
    static is_equal(const char* s); // sets the CWD for the function call

    operator = (const

    }


    /*
    Here the idea is to know the cwd, it is static, or no? It's not
    really static, in the sense that it's process level.

    The cwd is often static, where the automatic constructors of the
    getcwd type functions would install a callback
    so changing the cwd could be indicated to change them.

    Anyways they are static working directories, or simply the closest
    matching input of the previous.

    So, they are influenced by the parameters, because, the function
    should be about whatever is the mode of the string.

    So, I want it to get the cwd, doing so in a fair manner, and when
    should it reset the static?
    */

    /*


    */

    class open_flags
    {

    };

    class path_segment : public string
    {

    };

    class root // encapsulates a tree root (path root)
    {

    };

    class path_limits
    {
    // PATH_MAX, NAME_MAX
    }

    class path // encapsulates a file path
    {
    path(std::string s);
    path(const char* c);
    path(char* c);


    // these, C and C++ runtime types, specialize for platform
    path(fstream& f);
    path(FILE* fp);
    path(filedes_t fd);

    bool exists(); // object exists with this path?
    fstream* open(open_flags f); // pointer to new fstream with path and
    flags

    operator std::string ();
    operator char* ();

    std::list<path_segment> m_segments; // expose iterators over the
    segments, address at offset, bracketize
    // templatize functions outputting iterators on type generators

    // path components are string
    iterator& names_begin(); // there is list of names but also other
    objects
    iterator& names_end(); // there is list of names but also other
    objects

    // path segments are paths
    iterator& segments_begin();
    iterator& segments_end();
    };

    // construct the path as a string, it needs the tree sequencing for
    mapping and the path combinations

    class url
    {
    // it's like a path, has a path, query string
    }

    // here find the matching initial segments of the parameter and static
    path, finding the difference

    initial_match(string parameter, path static_path)
    {

    }
    f
    // return true and the match size and contents without realizing
    except as necessary
    // the matching string is matched to the matched string
    ret_t initial_match(string matching, string matched)
    {
    // use STL
    string::iterator matching_i = matching.begin();
    string::iterator matched_i = matched.begin();

    while(*matching_i == *matched_i)
    {
    ++matching_i;
    ++matched_i;
    // test for end to break
    // they both end at once or neither? no dereferencing end
    }
    // truncate matched
    matched.resize()
    }

    ret_t test_path(string file_name)
    {
    static path path_root; // cwd, current working directory
    static path path_mode; // parameter mode

    // mode is matching initial segment
    path_mode = initial_match(file_name, path_mode);

    // truncate the parameter,
    file_name = file_name.substr(initial_match_length);
    // for strings that aren't freed in this function, increment/reset
    the pointer
    // for strings freed in this function, delete and make new or
    otherwise pass in iterator, reset beginning

    // did the cwd change // now standard library calls see the input
    rel. the cwd
    }

    // bracketize file name in path segment component, with generating
    matchers of
    // input across mode and selectors with small special character lists
    and default
     
    Ross A. Finlayson, Oct 9, 2009
    #3
  4. Peter

    James Kanze Guest

    On Oct 9, 1:18 am, Peter <> wrote:
    > I'm a little bit at loss, why the new C++ standard (C++0x)
    > does not include something like Windows structured exception
    > handling.


    Two reasons, really. The first is a killer: it can't be
    implemented on a lot of platforms (e.g. those without memory
    management or protection). The second is simply that it is a
    bad idea.

    > I certainly prefer a C++ Exception to a signal, as the signal
    > only gives you the choice to terminate the process or mess
    > around with something as ugly as setjmp/longjmp.


    And when do you get a structured exception? Only when there is
    a serious program error, such that you can no longer be sure of
    the environment, and the only reasonable thing (for most
    applications) is to abort, as quickly as possible.

    > And such signals/exceptions can sometimes not be avoided, e.g.
    > in case of the system runs out of disk space while writing
    > into memory created by memory mapped io from a sparse file.


    Which is definitely a special case; the C++ language itself
    doesn't support memory mapped files or sparse files. Whatever
    happens in such cases is implementation defined.

    > Even in case of a null pointer access I would prefer to keep
    > the application running to be able to terminate it correctly.


    So check for null, and do whatever you want.

    > In this case probably there is no need to try to execute the
    > last verb again, because it will run into the same null
    > pointer access -- but at least the destructors should work and
    > the application can be terminated correctly.


    The problem is that when you've got an access violation
    (accessing memory which doesn't belong to the process), it's
    usually due to some previous memory overwrite, and you can't
    (safely) execute destructors.

    (This obviously depends on the application. There is a definite
    risk that executing destructors will do more harm than good, and
    most applications probably shouldn't take that risk, but some,
    like games programs, can't do much real harm, and it's worth the
    risk.)

    --
    James Kanze
     
    James Kanze, Oct 9, 2009
    #4
  5. Peter

    James Kanze Guest

    On Oct 9, 2:05 am, Victor Bazarov <> wrote:
    > Peter wrote:
    > Signals aren't really normative, are they?


    The standard defines a function to set signal handlers, and
    defines a couple of functions which raise specified signals
    (abort and raise); it also specifies a minimum that an
    implementation must allow being done in a signal handler. Most
    signals that occur in actual practice (things like SIGSEGV or
    SIGKILL under Unix, for example), however, are implementation
    defined, and most implementations do extend what you're allowed
    to do in a signal handler (but not generally to the point of
    allowing an exception to be thrown---for the simple reason that
    this is not practically implementable on most platforms).

    --
    James Kanze
     
    James Kanze, Oct 9, 2009
    #5
  6. Peter

    Peter Guest

    On Oct 9, 12:49 am, James Kanze <> wrote:
    > Two reasons, really.  The first is a killer: it can't be
    > implemented on a lot of platforms (e.g. those without memory
    > management or protection).  




    So you are suggesting that we remove the C++ feature,
    which allows calling via a virtual method table
    so to we are able to run C++ programs on CPUs from 1960.


    > The second is simply that it is a
    > bad idea.



    If you think like that, you should read up again about the differences
    of signal handling and exception handling.


    > > I certainly prefer a C++Exceptionto a signal, as the signal
    > > only gives you the choice to terminate the process or mess
    > > around with something as ugly as setjmp/longjmp.

    >
    > And when do you get a structuredexception?  Only when there is
    > a serious program error, such that you can no longer be sure of
    > the environment, and the only reasonable thing (for most
    > applications) is to abort, as quickly as possible.



    I gave 3 examples where an exception like on windows is helpful or
    even needed.
    Read my post again.


    > > And such signals/exceptions can sometimes not be avoided, e.g.
    > > in case of the system runs out of disk space while writing
    > > into memory created by memory mapped io from a sparse file.

    >
    > Which is definitely a special case; the C++ language itself
    > doesn't support memory mapped files or sparse files.  Whatever
    > happens in such cases is implementation defined.




    Yes again -- you could start removing features of C++ to enable it to
    cover more platforms.


    > > Even in case of a null pointer access I would prefer to keep
    > > the application running to be able to terminate it correctly.

    >
    > So check for null, and do whatever you want.



    You definitely did not get the main advantages of exception handling
    (and you're posting answers in this forum??????):
    1) no need to check for success anymore
    2) being able to catch errors 0 or more levels down the stack
    3) being able to abort constructors


    >
    > > In this case probably there is no need to try to execute the
    > > last verb again, because it will run into the same null
    > > pointer access -- but at least the destructors should work and
    > > the application can be terminated correctly.

    >
    > The problem is that when you've got an access violation
    > (accessing memory which doesn't belong to the process), it's
    > usually due to some previous memory overwrite, and you can't
    > (safely) execute destructors.



    You did not read my post. I gave multiple useful examples.



    I think you should not be posting answers to this forum.
    Also -- being able to understand written english is also helpful.
     
    Peter, Oct 12, 2009
    #6
  7. Peter

    Peter Guest

    On Oct 8, 6:05 pm, Victor Bazarov <> wrote:
    > Peter wrote:
    > > I'm a little bit at loss, why the new C++ standard (C++0x) does not
    > > include something like Windows structuredexceptionhandling.

    >
    > Why should it be included in the Standard (new or old) when any
    > implementation is free to provide its own way of dealing with those?



    You seem not able to understand the need for a standard.


    > > I certainly prefer a C++Exceptionto a signal, as the signal only
    > > gives you the choice to terminate the process or mess around with
    > > something as ugly as setjmp/longjmp.

    >
    > Signals aren't really normative, are they?


    > > And such signals/exceptions can sometimes not be avoided, e.g. in case
    > > of the system runs out of disk space while writing into memory created
    > > by memory mapped io from a sparse file.

    >
    > > Even in case of a null pointer access I would prefer to keep the
    > > application running to be able to terminate it correctly.

    >
    > Access to null pointer has undefined behaviour.  The implementation is
    > free to define it.  Some do.  Some don't.  There is no need to introduce
    > limitations by specifying what should happen.



    Read my post. I gave multiple examples fro such need.


    >
    >  > In this case
    >
    > > probably there is no need to try to execute the last verb again,
    > > because it will run into the same null pointer access -- but at least
    > > the destructors should work and the application can be terminated
    > > correctly.

    >
    > Whatever.  If you're using a sophisticated operating system that allows
    > you to handle such a situation, be happy.  You seem unhappy for some
    > reason.  Do you want your Windows application with all the SEH stuff be
    > runable on MS-DOS?  And you want the language to provide the means?  I
    > do not see this as reasonable.



    I was asking why this obviously useful feature (structured exception
    handling)
    is not part of the standard.
    Why are you bringing up MSDOS?


    >
    > > Another example is a floating pointexception.
    > > Withexceptionhandling I could avoid having to secure the code
    > > against invalid inputs,
    > > which also slows it down.

    >
    > Slows it down?  By how much?  I've worked in systems that were set up to
    > handle FP exceptions and invalid pointer access...  If you want it done
    > right, every damn function has to be littered with try/catch for those.



    The advantage of C++ exception handling is that you do not have to
    check for success everywhere.
    Try-catch-blocks should be rare in good code.
    If you are not aware of this, you should not be aswering questions
    here.


    >   It is much, MUCH, easier to make sure you never try to calculate a
    > logarithm of a negative value or you never hang onto a dangling pointer.
    >   A test for greater than 0 is so much quicker than setting everything
    > up for stack unwinding...



    I'm not talking about a single fallible call to log() or sqrt() or asin
    ().
    I'm talking about some 1000 lines of math code, with multiple inputs
    and multiple outputs.
    Or maybe even higher up in the call-stack -- our simulator only needs
    to know, that there was a single instance of some model
    (and there are a couple of thousands with every model having around
    1000 lines of math code),
    which was unable to deal with the current voltage vector.

    >
    > But you don't have to listen to me.  If you see how Microsoft Structured
    > Exceptions can be brought into the language and implemented everywhere
    > the C++ compilers can exist, do write it up.  I am sure folks in
    > comp.std.c++ will read your proposal with the same attention they give
    > every proposal.



    I just wanted to express my curiousity about the fact, that they
    (being smart people) did not get this idea by themselfs already.
     
    Peter, Oct 12, 2009
    #7
  8. Peter

    James Kanze Guest

    On Oct 12, 1:14 am, Peter <> wrote:
    > On Oct 9, 12:49 am, James Kanze <> wrote:


    > > Two reasons, really. The first is a killer: it can't be
    > > implemented on a lot of platforms (e.g. those without memory
    > > management or protection).


    > So you are suggesting that we remove the C++ feature, which
    > allows calling via a virtual method table so to we are able to
    > run C++ programs on CPUs from 1960.


    I don't know of any machine which can't support virtual
    functions. Even today, however, machines which can raise an
    asynchronous exception are rare.

    > > The second is simply that it is a bad idea.


    > If you think like that, you should read up again about the
    > differences of signal handling and exception handling.


    If you don't think like that, you should read up about how to
    write robust software. The difference is not between signal
    handling and exceptions; the difference is between immediately
    aborting and doing a stack walkback.

    > > > I certainly prefer a C++Exceptionto a signal, as the
    > > > signal only gives you the choice to terminate the process
    > > > or mess around with something as ugly as setjmp/longjmp.


    > > And when do you get a structuredexception? Only when there
    > > is a serious program error, such that you can no longer be
    > > sure of the environment, and the only reasonable thing (for
    > > most applications) is to abort, as quickly as possible.


    > I gave 3 examples where an exception like on windows is
    > helpful or even needed. Read my post again.


    You gave a few examples of exceptional cases. We certainly
    don't want to start requiring something that is detrimental in
    most cases, just to support some rare and special case.

    > > > And such signals/exceptions can sometimes not be avoided,
    > > > e.g. in case of the system runs out of disk space while
    > > > writing into memory created by memory mapped io from a
    > > > sparse file.


    > > Which is definitely a special case; the C++ language itself
    > > doesn't support memory mapped files or sparse files.
    > > Whatever happens in such cases is implementation defined.


    > Yes again -- you could start removing features of C++ to
    > enable it to cover more platforms.


    There's no feature here to remove. C++ doesn't support memory
    mapped files or sparse files.

    > > > Even in case of a null pointer access I would prefer to
    > > > keep the application running to be able to terminate it
    > > > correctly.


    > > So check for null, and do whatever you want.


    > You definitely did not get the main advantages of exception
    > handling (and you're posting answers in this forum??????):
    > 1) no need to check for success anymore
    > 2) being able to catch errors 0 or more levels down the stack
    > 3) being able to abort constructors


    I understand when and where to use exceptions. I also
    understand that when it comes to error reporting, one size
    doesn't fit all. If you don't check for null, then passing a
    null pointer is a programming error. In most applications, that
    means that you need to abort as quickly as possible. Without
    running the risk of executing destructors and the like, which
    might even make the situation worse.

    > > > In this case probably there is no need to try to execute the
    > > > last verb again, because it will run into the same null
    > > > pointer access -- but at least the destructors should work and
    > > > the application can be terminated correctly.


    > > The problem is that when you've got an access violation
    > > (accessing memory which doesn't belong to the process), it's
    > > usually due to some previous memory overwrite, and you can't
    > > (safely) execute destructors.


    > You did not read my post. I gave multiple useful examples.


    And you are intentionally missing the point: we don't want to
    require behavior that is detrimental most of the time, just to
    support some rare and unusual case.

    > I think you should not be posting answers to this forum.


    Really? Just because I don't want to make the language unusable
    for most serious applications, just to support some special
    case.

    > Also -- being able to understand written english is also
    > helpful.


    If that were a requirement, you couldn't have posted the above,
    since you manifestly didn't understand a word I wrote.

    --
    James Kanze
     
    James Kanze, Oct 12, 2009
    #8
  9. Peter

    Peter Guest

    On Oct 12, 5:10 am, James Kanze <> wrote:
    > I don't know of any machine which can't support virtual
    > functions.  Even today, however, machines which can raise an
    > asynchronousexceptionare rare.



    The first CPU I came in contact with (Z80) did not have any feature to
    call via a pointer stored somewhere -- it could call only to a fixed
    address. Maybe you could emulate it via manipulating the stack and
    executing return.

    The standard could simply claim, that on machines which support memory
    protection, a C++ exception should be thrown instead of a signal. This
    would cover all of the platforms I have to deal with (various UNIXs
    and Windows).
     
    Peter, Oct 12, 2009
    #9
  10. Peter

    James Kanze Guest

    On Oct 12, 7:57 pm, Peter <> wrote:
    > On Oct 12, 5:10 am, James Kanze <> wrote:


    > > I don't know of any machine which can't support virtual
    > > functions. Even today, however, machines which can raise an
    > > asynchronousexceptionare rare.


    > The first CPU I came in contact with (Z80) did not have any
    > feature to call via a pointer stored somewhere -- it could
    > call only to a fixed address. Maybe you could emulate it via
    > manipulating the stack and executing return.


    The instruction set of the Z80 was a superset of that of the
    8080, and the languages I used on the 8080 certainly supported
    indirect calls. I think that they did simply push the address
    onto the stack, and then do a ret; another alternative would
    have been modifying the address in a jmp instruction; not very
    thread safe, but that was never an issue on an 8080.

    > The standard could simply claim, that on machines which
    > support memory protection, a C++ exception should be thrown
    > instead of a signal. This would cover all of the platforms I
    > have to deal with (various UNIXs and Windows).


    Except that this can't be made to work under Solaris, on a
    Sparc. And more generally, the fact that C++ doesn't throw an
    exception in such cases is a major reason why people continue to
    use it---if there is an error in your code, an exception is the
    last thing you want. (A C++ exception, anyway, with destructors
    being called.)

    --
    James Kanze
     
    James Kanze, Oct 12, 2009
    #10
  11. Peter

    Noah Roberts Guest

    In article <62f74dc5-490a-416d-8e3b-658690942e41
    @b25g2000prb.googlegroups.com>, says...
    >
    > I'm a little bit at loss, why the new C++ standard (C++0x) does not
    > include something like Windows structured exception handling.
    > I certainly prefer a C++ Exception to a signal, as the signal only
    > gives you the choice to terminate the process or mess around with
    > something as ugly as setjmp/longjmp.


    Because signals and exceptions are for totally different things.

    > And such signals/exceptions can sometimes not be avoided, e.g. in case
    > of the system runs out of disk space while writing into memory created
    > by memory mapped io from a sparse file.
    >
    > Even in case of a null pointer access I would prefer to keep the
    > application running to be able to terminate it correctly. In this case
    > probably there is no need to try to execute the last verb again,
    > because it will run into the same null pointer access -- but at least
    > the destructors should work and the application can be terminated
    > correctly.


    Use a smart pointer and throw an exception when ->* is called on 0.

    >
    > Another example is a floating point exception.
    > With exception handling I could avoid having to secure the code
    > against invalid inputs,
    > which also slows it down.


    Some may disagree but I'd recommend against this line of reasoning.
    Exception handling is not a replacement for input validation.
     
    Noah Roberts, Oct 12, 2009
    #11
  12. Peter

    REH Guest

    On Oct 12, 1:57 pm, Peter <> wrote:
    > The first CPU I came in contact with (Z80) did not have any feature to
    > call via a pointer stored somewhere -- it could call only to a fixed
    > address. Maybe you could emulate it via manipulating the stack and
    > executing return.


    What are you talking about? I've programmed Z80s for years. You can
    jump to an address contained in the HL register pair: JMP (HL). You
    can jump indirectly to an address stored in memory JMP (nn). Call has
    the same ability.

    REH
     
    REH, Oct 12, 2009
    #12
  13. Peter

    REH Guest

    On Oct 12, 5:36 pm, REH <> wrote:
    > On Oct 12, 1:57 pm, Peter <> wrote:
    >
    > > The first CPU I came in contact with (Z80) did not have any feature to
    > > call via a pointer stored somewhere -- it could call only to a fixed
    > > address. Maybe you could emulate it via manipulating the stack and
    > > executing return.

    >
    > What are you talking about? I've programmed Z80s for years. You can
    > jump to an address contained in the HL register pair: JMP (HL). You
    > can jump indirectly to an address stored in memory JMP (nn). Call has
    > the same ability.
    >


    I looked up the opcodes verify my statements (it been a while). I
    misremembered about JMP (nn) and call (that weirdly was how they
    always listed the direct jumps even though parentheses where used for
    indirection), but you can do an indirect jump via the HL register
    pair. You can also do it using IX and IY indexing registers. No need
    to manipulate the stack or make self-modifying code.

    REH
     
    REH, Oct 12, 2009
    #13
  14. Peter

    Peter Guest

    On Oct 12, 1:51 pm, Noah Roberts <> wrote:
    > > I'm a little bit at loss, why the new C++ standard (C++0x) does not
    > > include something like Windows structuredexceptionhandling.
    > > I certainly prefer a C++Exceptionto a signal, as the signal only
    > > gives you the choice to terminate the process or mess around with
    > > something as ugly as setjmp/longjmp.

    >
    > Because signals and exceptions are for totally different things.



    Yes. E.g. "signals" is spelled fully differently than "exceptions".
    What is your point?


    > > And such signals/exceptions can sometimes not be avoided, e.g. in case
    > > of the system runs out of disk space while writing into memory created
    > > by memory mapped io from a sparse file.

    >
    > > Even in case of a null pointer access I would prefer to keep the
    > > application running to be able to terminate it correctly. In this case
    > > probably there is no need to try to execute the last verb again,
    > > because it will run into the same null pointer access -- but at least
    > > the destructors should work and the application can be terminated
    > > correctly.

    >
    > Use a smart pointer and throw anexceptionwhen ->* is called on 0.



    This would involve an if-statement which results in additional machine
    instructions.
    The CPU is anyway checking for invalid memory access.


    > > Another example is a floating pointexception.
    > > Withexceptionhandling I could avoid having to secure the code
    > > against invalid inputs,
    > > which also slows it down.

    >
    > Some may disagree but I'd recommend against this line of reasoning.  Exceptionhandling is
    > not a replacement for input validation.



    To know exactly which input values are going to result in a NAN or INF
    value
    is not possible for my code.
     
    Peter, Oct 13, 2009
    #14
  15. Peter

    Peter Guest

    On Oct 12, 12:28 pm, James Kanze <> wrote:
    > > The standard could simply claim, that on machines which
    > > support memory protection, a C++exceptionshould be thrown
    > > instead of a signal. This would cover all of the platforms I
    > > have to deal with (various UNIXs and Windows).

    >
    > Except that this can't be made to work under Solaris, on a
    > Sparc.  



    SOLARIS also has signals for SIGSEGV and floating point exceptions.

    I used to convert structured exceptions on Windows into C++ exceptions
    by setting the matching handler and throw from this handler a C++
    exception matching the structured exception code -- to be able to
    catch different types of exceptions depending on what had happend.

    Both, the signal handlers and structured exception handling are
    asynchron.
    I think it is just a matter of the compiler -- to create code, which
    is able to deal with exceptions thrown from a signal handler --
    compiler switch /EHa with Microsofts Visual C++.


    > And more generally, the fact that C++ doesn't throw anexceptionin such cases is a major
    > reason why people continue to
    > use it---if there is an error in your code, anexceptionis the
    > last thing you want.  (A C++exception, anyway, with destructors
    > being called.)



    I'm not following.
    You are saying, that the reason people use C++ exception handling is
    that it does not cover SIGSEGV?
    I've never heared anybody complain about the existence of structured
    exception handling on Windows.

    Please explain why you could not do whatever you are doing in a signal
    handler
    in the matching exception handler (which is also a function which can
    be installed like a signal handler).
     
    Peter, Oct 13, 2009
    #15
  16. Peter wrote:
    > [..]
    >>> Another example is a floating pointexception.
    >>> Withexceptionhandling I could avoid having to secure the code
    >>> against invalid inputs,
    >>> which also slows it down.

    >> Some may disagree but I'd recommend against this line of reasoning. Exceptionhandling is
    >> not a replacement for input validation.

    >
    >
    > To know exactly which input values are going to result in a NAN or INF
    > value
    > is not possible for my code.


    It's not "not possible". It *probably* requires more effort than you're
    willing to expend. Hardware FP exceptions are produced by some
    calculations that usually can be identified and singled out for input
    verification. For example, when calculating inverse matrix using the
    determinant method, you only need to check the value of the determinant
    once to avoid dividing by 0. You could also avoid overflow or underflow
    by predicting the result of dividing by a large value or by a small
    value. When you're about to calculate a square root, check the value
    for negativity (and don't do it if it's negative). And so on. What you
    seem to advocate is the use of exceptions (which can be quite expensive)
    instead of picking apart your FP expressions to find the subexpressions
    that can cause problems and then inserting simple, efficient (trust me,
    they usually are) and more explicit checks. Those checks would allow
    you to identify the problem to your user with much better detail than
    the exceptions would.

    Programming languages were created by lazy programmers. Programmers
    should be lazy to be more productive (however paradoxical it sounds).
    So, to paraphrase Einstein, be as lazy as possible, but not lazier.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Oct 13, 2009
    #16
  17. Peter

    Ian Collins Guest

    Peter wrote:
    > On Oct 12, 12:28 pm, James Kanze <> wrote:
    >>> The standard could simply claim, that on machines which
    >>> support memory protection, a C++exceptionshould be thrown
    >>> instead of a signal. This would cover all of the platforms I
    >>> have to deal with (various UNIXs and Windows).

    >> Except that this can't be made to work under Solaris, on a
    >> Sparc.

    >
    >
    > SOLARIS also has signals for SIGSEGV and floating point exceptions.
    >
    > I used to convert structured exceptions on Windows into C++ exceptions
    > by setting the matching handler and throw from this handler a C++
    > exception matching the structured exception code -- to be able to
    > catch different types of exceptions depending on what had happend.
    >
    > Both, the signal handlers and structured exception handling are
    > asynchron.
    > I think it is just a matter of the compiler -- to create code, which
    > is able to deal with exceptions thrown from a signal handler --
    > compiler switch /EHa with Microsofts Visual C++.


    I don't think you'll find any *nix compiler/runtime that supports
    throwing exceptions from a signal handler.

    --
    Ian Collins
     
    Ian Collins, Oct 14, 2009
    #17
  18. Peter

    James Kanze Guest

    On Oct 13, 8:31 pm, Peter <> wrote:
    > On Oct 12, 12:28 pm, James Kanze <> wrote:


    > > > The standard could simply claim, that on machines which
    > > > support memory protection, a C++exceptionshould be thrown
    > > > instead of a signal. This would cover all of the platforms
    > > > I have to deal with (various UNIXs and Windows).


    > > Except that this can't be made to work under Solaris, on a
    > > Sparc.


    > SOLARIS also has signals for SIGSEGV and floating point exceptions.


    Yes, but you can't throw an exception from a signal handler.

    > I used to convert structured exceptions on Windows into C++
    > exceptions by setting the matching handler and throw from this
    > handler a C++ exception matching the structured exception code
    > -- to be able to catch different types of exceptions depending
    > on what had happend.


    Once you have a structured exception under Windows, you are in
    the exception handling mechanism.

    > Both, the signal handlers and structured exception handling are
    > asynchron.


    Under Windows. Most systems don't support asynchronous
    exceptions; it's not trivial.

    > I think it is just a matter of the compiler -- to create code,
    > which is able to deal with exceptions thrown from a signal
    > handler -- compiler switch /EHa with Microsofts Visual C++.


    It depends more on the API, and how the stack is set up. Under
    Solaris, on a Sparc, at least, there are moments when a stack
    walkback is not possible. Throw an exception in one of these,
    and you're hosed. (I really suspect that the same thing is true
    under Windows, and that there are combinations of circumstances
    where structured exceptions don't work. Ensuring that you can
    trigger a stack walkback asynchronously can be very expensive in
    terms of runtime, even on an 80x86.)

    > > And more generally, the fact that C++ doesn't throw
    > > anexceptionin such cases is a major reason why people
    > > continue to use it---if there is an error in your code,
    > > anexceptionis the last thing you want. (A C++exception,
    > > anyway, with destructors being called.)


    > I'm not following.
    > You are saying, that the reason people use C++ exception handling is
    > that it does not cover SIGSEGV?


    No. I'm saying that one reason people use C++ (instead of e.g.
    Java) is because it doesn't convert e.g. a null pointer
    dereference into an exception, but rather aborts the process.
    (It's only one reason, of course. There are a lot of others.)

    > I've never heared anybody complain about the existence of
    > structured exception handling on Windows.


    That's because most serious programmers don't use it. In most
    contexts, I'll compile with /EHs.

    Note that I'm all in favor of compilers offering structured
    exceptions as an option, if they can. There are cases where it
    is useful and appropriate. But it would be a serious flaw in
    the language to require it, because most of the time, it is not
    a good solution, and because most system API's can't reliably
    support it. This is one case where "undefined behavior" is
    precisely the best possible solution, since it leaves the
    implementor free to offer the best solution possible for his
    customers, on his platforms. Including offering a choice of
    solutions, as does Microsoft.

    > Please explain why you could not do whatever you are doing in
    > a signal handler in the matching exception handler (which is
    > also a function which can be installed like a signal handler).


    Because a signal can occur asynchronously. At the moment the
    code is adjusting the stack, for example. It's often possible
    to ensure that there is no critical moment (although I don't
    think it's possible on a Sparc, given the way the register stack
    works), but requiring this also excludes any number of
    optimization techniques, which means that many applications will
    take a performance hit from it.

    --
    James Kanze
     
    James Kanze, Oct 14, 2009
    #18
  19. Peter

    James Kanze Guest

    On Oct 14, 4:54 am, Ian Collins <> wrote:
    > Peter wrote:
    > > On Oct 12, 12:28 pm, James Kanze <> wrote:
    > >>> The standard could simply claim, that on machines which
    > >>> support memory protection, a C++exceptionshould be thrown
    > >>> instead of a signal. This would cover all of the platforms
    > >>> I have to deal with (various UNIXs and Windows).
    > >> Except that this can't be made to work under Solaris, on a
    > >> Sparc.


    > > SOLARIS also has signals for SIGSEGV and floating point
    > > exceptions.


    > > I used to convert structured exceptions on Windows into C++
    > > exceptions by setting the matching handler and throw from
    > > this handler a C++ exception matching the structured
    > > exception code -- to be able to catch different types of
    > > exceptions depending on what had happend.


    > > Both, the signal handlers and structured exception handling
    > > are asynchron.
    > > I think it is just a matter of the compiler -- to create
    > > code, which is able to deal with exceptions thrown from a
    > > signal handler -- compiler switch /EHa with Microsofts
    > > Visual C++.


    > I don't think you'll find any *nix compiler/runtime that
    > supports throwing exceptions from a signal handler.


    Officially, or practically:)? I think most compilers fail to
    document this. (I know of the problems under Solaris on a Sparc
    from personal conversations with the authors of Sun CC. Not
    from documentation.)

    Of course, the Posix standard says that there are only a limited
    number of things you can do in a signal handler, and raising an
    exception obviously isn't one of them. But the Posix standard
    is only concerned with C; it doesn't say you can call a virtual
    function, either, but that's not a problem.

    More generally: how does Microsoft handle structured exceptions
    if the fault occurs when malloc is in the middle of updating its
    data structures? Of course, this can only happen if you've
    corrupted the free space arena somehow (or there is a bug in
    malloc), but isn't that one of the most common causes of a
    segment violation?

    More generally, implementable or not, structured exceptions
    aren't reliable. There are special cases (e.g. plug-ins for
    non-critical applications) where they represent an acceptable
    risk, especially since with the Microsoft compiler, each plug-in
    (DLL) has its own heap, but I certainly wouldn't use them in
    anything critical.

    --
    James Kanze
     
    James Kanze, Oct 14, 2009
    #19
  20. In message <>, Ian Collins
    <> writes
    >Peter wrote:
    >> On Oct 12, 12:28 pm, James Kanze <> wrote:
    >>>> The standard could simply claim, that on machines which
    >>>> support memory protection, a C++exceptionshould be thrown
    >>>> instead of a signal. This would cover all of the platforms I
    >>>> have to deal with (various UNIXs and Windows).
    >>> Except that this can't be made to work under Solaris, on a
    >>> Sparc.

    >> SOLARIS also has signals for SIGSEGV and floating point exceptions.
    >> I used to convert structured exceptions on Windows into C++
    >>exceptions
    >> by setting the matching handler and throw from this handler a C++
    >> exception matching the structured exception code -- to be able to
    >> catch different types of exceptions depending on what had happend.
    >> Both, the signal handlers and structured exception handling are
    >> asynchron.
    >> I think it is just a matter of the compiler -- to create code, which
    >> is able to deal with exceptions thrown from a signal handler --
    >> compiler switch /EHa with Microsofts Visual C++.

    >
    >I don't think you'll find any *nix compiler/runtime that supports
    >throwing exceptions from a signal handler.
    >

    ... and if it did, presumably the exceptions would propagate back up the
    kernel stack [*] that invoked the signal handler, not the user stack
    where the interrupted program is running.

    This is an important difference between signals and exceptions: signal
    handlers are just free functions called asynchronously, but exceptions
    are raised in the context of an entire stack of function calls which
    have to be unwound, cleanly destroying automatic objects as the
    exception propagates.

    If a signal happens during the execution of a class member function, the
    class invariant may not be satisfied at that moment, which makes it
    somewhat difficult to propagate an exception in an exception-safe manner
    ;-(

    [*] or whatever the equivalent terminology for user/kernel etc. is in
    the system of your choice ;-)

    --
    Richard Herring
     
    Richard Herring, Oct 14, 2009
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael Pronath
    Replies:
    1
    Views:
    1,175
    Diez B. Roggisch
    Jan 3, 2005
  2. John Perks and Sarah Mount

    Block-structured resource handling via decorators

    John Perks and Sarah Mount, Jul 29, 2005, in forum: Python
    Replies:
    5
    Views:
    296
    John Perks and Sarah Mount
    Jul 30, 2005
  3. George2

    Structured exception

    George2, Jan 19, 2008, in forum: C++
    Replies:
    1
    Views:
    291
    Rolf Magnus
    Jan 19, 2008
  4. George2
    Replies:
    4
    Views:
    405
    Mike Smith
    Jan 28, 2008
  5. George2
    Replies:
    15
    Views:
    898
    Alf P. Steinbach
    Jan 29, 2008
Loading...

Share This Page