Re: Is there a good use case for noexcept?

Discussion in 'C++' started by Stefan Ram, Apr 24, 2011.

  1. Stefan Ram

    Stefan Ram Guest

    Alexander Terekhov <> writes in comp.lang.c++.moderated:
    >DeMarcus wrote:
    >[...]
    >>The problem is that stack exhaustion (out-of-stack-memory) is also a
    >>failure, so even the simple function std::swap may fail.

    >Exactly! And the runtime behaviour should be the same as with
    > int f() { // implicit nothrow/noexcept
    > throw 0;
    > }
    >No?
    >C'mon, a noexcept function shall call abort() (C++ terminate()) on
    >throw / stack exhaustion.


    A libraryable function should return control to its caller
    whenever possible. And usually, an exhausted stack will be
    relieved more by returning than by calling.

    I also wonder whether you suggest that every (noexecept)
    function should always check explicitly for stack exhaustion
    and try to specify a behavior for this.

    Is anyone here who uses »abort()« at all?

    I assume nearly all the programs we write operate under the
    »optimistic« assumption that there always is enough stack,
    while at the same time try to avoid being too careless about
    it, that is, trying to avoid deep recursion and so.

    This might be not good enough for high-security
    applications, where one would like to have some call like
    »size_t autostorage()« that gives the amount of automatic
    storage still available.
    Stefan Ram, Apr 24, 2011
    #1
    1. Advertising

  2. Stefan Ram

    James Kanze Guest

    On Apr 24, 4:07 pm, -berlin.de (Stefan Ram) wrote:
    > Alexander Terekhov <> writes in comp.lang.c++.moderated:


    > >DeMarcus wrote:
    > >[...]
    > >>The problem is that stack exhaustion (out-of-stack-memory)
    > >>is also a failure, so even the simple function std::swap may
    > >>fail.

    > >Exactly! And the runtime behaviour should be the same as with
    > > int f() { // implicit nothrow/noexcept
    > > throw 0;
    > > }
    > >No?
    > >C'mon, a noexcept function shall call abort() (C++
    > >terminate()) on throw / stack exhaustion.


    Stack exhaustion is undefined behavior in C++. Mainly because
    C++ generates and executes native code, and in native code,
    stack exhaustion is handled by the OS; there's nothing the
    generated code can do to trap it, or even to detect it.

    > A libraryable function should return control to its caller
    > whenever possible. And usually, an exhausted stack will be
    > relieved more by returning than by calling.


    :) Usually, an exhausted stack will either result in a core
    dump, or overwriting memory that isn't part of the stack. (The
    latter can easily occur in multithreaded environments, if the
    stack for each thread is allocated in the general free store.)

    > I also wonder whether you suggest that every (noexecept)
    > function should always check explicitly for stack exhaustion
    > and try to specify a behavior for this.


    It would be nice, if it were possible.

    > Is anyone here who uses »abort()« at all?


    Anyone developing critical applications. And probably a lot of
    others.

    > I assume nearly all the programs we write operate under the
    > »optimistic« assumption that there always is enough stack,
    > while at the same time try to avoid being too careless about
    > it, that is, trying to avoid deep recursion and so.


    Agreed. Along with a couple of other optimistic assumptions:
    there will be enough memory, an int won't overflow, etc.
    Ideally, we'd like 1) to be able to validate our assumptions up
    front (usually possible for int overflowing, not so easy for the
    other cases), and 2) have the program fail immediately if the
    assumption fails.

    > This might be not good enough for high-security
    > applications, where one would like to have some call like
    > »size_t autostorage()« that gives the amount of automatic
    > storage still available.


    One would like a lot of things. One doesn't always get them:).

    --
    James Kanze
    James Kanze, Apr 25, 2011
    #2
    1. Advertising

  3. Stefan Ram

    jacob navia Guest

    Le 25/04/11 17:55, James Kanze a écrit :
    >
    > Stack exhaustion is undefined behavior in C++. Mainly because
    > C++ generates and executes native code, and in native code,
    > stack exhaustion is handled by the OS; there's nothing the
    > generated code can do to trap it, or even to detect it.
    >


    Under windows this is just wrong. You can trap stack exhaustion using the

    __try / __except

    construct, and act accordingly, maybe jumping into a recovery context
    with setjmp/longjmp

    I would be surprised that under linux you couldn't do that too.
    jacob navia, Apr 25, 2011
    #3
  4. On Apr 25, 12:28 pm, Paavo Helde <> wrote:
    > jacob navia <> wrote in news:ip48fl$p55$1
    > @speranza.aioe.org:
    >
    >
    >
    > > Le 25/04/11 17:55, James Kanze a écrit :

    >
    > >> Stack exhaustion is undefined behavior in C++.  Mainly because
    > >> C++ generates and executes native code, and in native code,
    > >> stack exhaustion is handled by the OS; there's nothing the
    > >> generated code can do to trap it, or even to detect it.

    >
    > > Under windows this is just wrong. You can trap stack exhaustion using

    > the
    >
    > > __try / __except

    >
    > > construct, and act accordingly, maybe jumping into a recovery context
    > > with setjmp/longjmp

    >
    > It is not so easy as you make it sound. For catching SEH exceptions in
    > Windows more or less reliably one must specify the /EHa compiler option,
    > otherwise these exceptions may leave C++ objects half-created or half-
    > destroyed. Using the /EHa compiler option will decrease performance all
    > over the place. Also longjmp does not play well with C++ objects, at the
    > best one may count on memory leaks.
    >
    > To continue execution after a stack overflow one must restore the stack
    > guard page. There are numerous rules about where this can be done(inside
    > a C++ catch handler it is prohibited, for example) and even then it can
    > fail. Seehttp://msdn.microsoft.com/en-us/library/89f73td2%28v=VS.100%
    > 29.aspx for details.


    I must agree with jacob navia that you can recover from an "out of
    stack" error in most cases on desktop OSes, although I agree with you
    that it is non-trivial, highly system dependent, and not guaranteed to
    work aka "hacky". However, assuming that your stack frame is smaller
    than the page guard size, it's quite doable. JVMs do it all the time
    AFAIK. I'm pretty sure you're guaranteed a SIGSEGV in POSIX, which
    IIRC is how JVMs do it on POSIX systems. All I know of win32 is what
    you just wrote.
    Joshua Maurice, Apr 25, 2011
    #4
  5. Stefan Ram

    Ian Collins Guest

    On 04/26/11 09:31 AM, Joshua Maurice wrote:
    > On Apr 25, 12:28 pm, Paavo Helde<> wrote:
    >> jacob navia<> wrote in news:ip48fl$p55$1
    >> @speranza.aioe.org:
    >>
    >>
    >>
    >>> Le 25/04/11 17:55, James Kanze a écrit :

    >>
    >>>> Stack exhaustion is undefined behavior in C++. Mainly because
    >>>> C++ generates and executes native code, and in native code,
    >>>> stack exhaustion is handled by the OS; there's nothing the
    >>>> generated code can do to trap it, or even to detect it.

    >>
    >>> Under windows this is just wrong. You can trap stack exhaustion using

    >> the
    >>
    >>> __try / __except

    >>
    >>> construct, and act accordingly, maybe jumping into a recovery context
    >>> with setjmp/longjmp

    >>
    >> It is not so easy as you make it sound. For catching SEH exceptions in
    >> Windows more or less reliably one must specify the /EHa compiler option,
    >> otherwise these exceptions may leave C++ objects half-created or half-
    >> destroyed. Using the /EHa compiler option will decrease performance all
    >> over the place. Also longjmp does not play well with C++ objects, at the
    >> best one may count on memory leaks.
    >>
    >> To continue execution after a stack overflow one must restore the stack
    >> guard page. There are numerous rules about where this can be done(inside
    >> a C++ catch handler it is prohibited, for example) and even then it can
    >> fail. Seehttp://msdn.microsoft.com/en-us/library/89f73td2%28v=VS.100%
    >> 29.aspx for details.

    >
    > I must agree with jacob navia that you can recover from an "out of
    > stack" error in most cases on desktop OSes, although I agree with you
    > that it is non-trivial, highly system dependent, and not guaranteed to
    > work aka "hacky".


    In other words, something that can't be standardised! All of the
    embedded OS I've used just kill or suspend the offending task/thread.

    --
    Ian Collins
    Ian Collins, Apr 25, 2011
    #5
  6. Stefan Ram

    James Kanze Guest

    On Apr 25, 5:45 pm, jacob navia <> wrote:
    > Le 25/04/11 17:55, James Kanze a écrit :
    > > Stack exhaustion is undefined behavior in C++. Mainly because
    > > C++ generates and executes native code, and in native code,
    > > stack exhaustion is handled by the OS; there's nothing the
    > > generated code can do to trap it, or even to detect it.


    > Under windows this is just wrong. You can trap stack exhaustion using the


    > __try / __except


    > construct, and act accordingly, maybe jumping into a recovery context
    > with setjmp/longjmp


    Have you actually tried this in a multithreaded environment?
    (It might work; as far as I can see, Windows does insist on
    defining all of the thread's stacks itself. But in practice,
    judging from what I've seen, catching stack overflow is
    problematic at best.)

    > I would be surprised that under linux you couldn't do that too.


    If it does, then Linux isn't Posix compliant.

    --
    James Kanze
    James Kanze, Apr 25, 2011
    #6
  7. Stefan Ram

    James Kanze Guest

    On Apr 25, 10:31 pm, Joshua Maurice <> wrote:
    > On Apr 25, 12:28 pm, Paavo Helde <> wrote:


    [...]
    > I must agree with jacob navia that you can recover from an "out of
    > stack" error in most cases on desktop OSes, although I agree with you
    > that it is non-trivial, highly system dependent, and not guaranteed to
    > work aka "hacky". However, assuming that your stack frame is smaller
    > than the page guard size, it's quite doable. JVMs do it all the time
    > AFAIK. I'm pretty sure you're guaranteed a SIGSEGV in POSIX, which
    > IIRC is how JVMs do it on POSIX systems.


    You are definitely not guaranteed a SIGSEGV in POSIX. Under
    POSIX, you can put the stack pretty much anywhere you want. And
    JVM's use their own stack, not the system stack, so they can do
    whatever checks are necessary.

    --
    James Kanze
    James Kanze, Apr 25, 2011
    #7
  8. Stefan Ram

    jacob navia Guest

    Le 25/04/11 23:58, James Kanze a écrit :
    > On Apr 25, 5:45 pm, jacob navia<> wrote:
    >> Le 25/04/11 17:55, James Kanze a écrit :
    >>> Stack exhaustion is undefined behavior in C++. Mainly because
    >>> C++ generates and executes native code, and in native code,
    >>> stack exhaustion is handled by the OS; there's nothing the
    >>> generated code can do to trap it, or even to detect it.

    >
    >> Under windows this is just wrong. You can trap stack exhaustion using the

    >
    >> __try / __except

    >
    >> construct, and act accordingly, maybe jumping into a recovery context
    >> with setjmp/longjmp

    >
    > Have you actually tried this in a multithreaded environment?
    > (It might work; as far as I can see, Windows does insist on
    > defining all of the thread's stacks itself. But in practice,
    > judging from what I've seen, catching stack overflow is
    > problematic at best.)
    >


    Based on what you have seen.

    >> I would be surprised that under linux you couldn't do that too.

    >
    > If it does, then Linux isn't Posix compliant.


    Obviously here you mean:

    "If linux would support the windows API it wouldn't be Posix compliant"

    in your efforts of misunderstanding what I said...

    I repeat:

    I would be surprised that under linux you can't catch stack overflow

    Happy now?
    jacob navia, Apr 26, 2011
    #8
  9. Stefan Ram

    Ian Collins Guest

    On 04/26/11 09:43 PM, jacob navia wrote:
    > Le 25/04/11 23:58, James Kanze a écrit :
    >> On Apr 25, 5:45 pm, jacob navia<> wrote:
    >>> Le 25/04/11 17:55, James Kanze a écrit :
    >>>> Stack exhaustion is undefined behavior in C++. Mainly because
    >>>> C++ generates and executes native code, and in native code,
    >>>> stack exhaustion is handled by the OS; there's nothing the
    >>>> generated code can do to trap it, or even to detect it.

    >>
    >>> Under windows this is just wrong. You can trap stack exhaustion using the

    >>
    >>> __try / __except

    >>
    >>> construct, and act accordingly, maybe jumping into a recovery context
    >>> with setjmp/longjmp

    >>
    >> Have you actually tried this in a multithreaded environment?
    >> (It might work; as far as I can see, Windows does insist on
    >> defining all of the thread's stacks itself. But in practice,
    >> judging from what I've seen, catching stack overflow is
    >> problematic at best.)
    >>

    >
    > Based on what you have seen.
    >
    >>> I would be surprised that under linux you couldn't do that too.

    >>
    >> If it does, then Linux isn't Posix compliant.

    >
    > Obviously here you mean:
    >
    > "If linux would support the windows API it wouldn't be Posix compliant"
    >
    > in your efforts of misunderstanding what I said...
    >
    > I repeat:
    >
    > I would be surprised that under linux you can't catch stack overflow


    I think the point James was making is with Posix threads, you can place
    the thread's stack anywhere, so there's no (reasonable) way to detect an
    overflow.

    --
    Ian Collins
    Ian Collins, Apr 26, 2011
    #9
  10. Stefan Ram

    jacob navia Guest

    Le 26/04/11 11:48, Ian Collins a écrit :
    >
    > I think the point James was making is with Posix threads, you can place
    > the thread's stack anywhere, so there's no (reasonable) way to detect an
    > overflow.
    >


    OK, then you just put a page of 4K addresses with no access behind your
    stacks. When stack is exhausted you arrive at that page and you get a
    segmentation violation that you can catch.
    jacob navia, Apr 26, 2011
    #10
  11. Stefan Ram

    Ian Collins Guest

    On 04/26/11 09:51 PM, jacob navia wrote:
    > Le 26/04/11 11:48, Ian Collins a écrit :
    >>
    >> I think the point James was making is with Posix threads, you can place
    >> the thread's stack anywhere, so there's no (reasonable) way to detect an
    >> overflow.
    >>

    >
    > OK, then you just put a page of 4K addresses with no access behind your
    > stacks. When stack is exhausted you arrive at that page and you get a
    > segmentation violation that you can catch.


    Maybe you could, but placing restrictions on such a basic feature of the
    OS is well beyond a language specification. On embedded systems where
    resources are tight, tuning stack sizes is common practice.

    --
    Ian Collins
    Ian Collins, Apr 26, 2011
    #11
  12. Stefan Ram

    jacob navia Guest

    Le 26/04/11 11:57, Ian Collins a écrit :
    > On 04/26/11 09:51 PM, jacob navia wrote:
    >> Le 26/04/11 11:48, Ian Collins a écrit :
    >>>
    >>> I think the point James was making is with Posix threads, you can place
    >>> the thread's stack anywhere, so there's no (reasonable) way to detect an
    >>> overflow.
    >>>

    >>
    >> OK, then you just put a page of 4K addresses with no access behind your
    >> stacks. When stack is exhausted you arrive at that page and you get a
    >> segmentation violation that you can catch.

    >
    > Maybe you could, but placing restrictions on such a basic feature of the
    > OS is well beyond a language specification. On embedded systems where
    > resources are tight, tuning stack sizes is common practice.
    >


    Yes, this supposes an MMU, and quite a lot of hardware behind...
    OK, I agree that in a general case is impossible.
    jacob navia, Apr 26, 2011
    #12
  13. On Apr 25, 2:55 pm, Ian Collins <> wrote:
    > On 04/26/11 09:31 AM, Joshua Maurice wrote:
    >
    >
    >
    > > On Apr 25, 12:28 pm, Paavo Helde<>  wrote:
    > >> jacob navia<>  wrote in news:ip48fl$p55$1
    > >> @speranza.aioe.org:

    >
    > >>> Le 25/04/11 17:55, James Kanze a écrit :

    >
    > >>>> Stack exhaustion is undefined behavior in C++.  Mainly because
    > >>>> C++ generates and executes native code, and in native code,
    > >>>> stack exhaustion is handled by the OS; there's nothing the
    > >>>> generated code can do to trap it, or even to detect it.

    >
    > >>> Under windows this is just wrong. You can trap stack exhaustion using
    > >> the

    >
    > >>> __try / __except

    >
    > >>> construct, and act accordingly, maybe jumping into a recovery context
    > >>> with setjmp/longjmp

    >
    > >> It is not so easy as you make it sound. For catching SEH exceptions in
    > >> Windows more or less reliably one must specify the /EHa compiler option,
    > >> otherwise these exceptions may leave C++ objects half-created or half-
    > >> destroyed. Using the /EHa compiler option will decrease performance all
    > >> over the place. Also longjmp does not play well with C++ objects, at the
    > >> best one may count on memory leaks.

    >
    > >> To continue execution after a stack overflow one must restore the stack
    > >> guard page. There are numerous rules about where this can be done(inside
    > >> a C++ catch handler it is prohibited, for example) and even then it can
    > >> fail. Seehttp://msdn.microsoft.com/en-us/library/89f73td2%28v=VS.100%
    > >> 29.aspx for details.

    >
    > > I must agree with jacob navia that you can recover from an "out of
    > > stack" error in most cases on desktop OSes, although I agree with you
    > > that it is non-trivial, highly system dependent, and not guaranteed to
    > > work aka "hacky".

    >
    > In other words, something that can't be standardised!  All of the
    > embedded OS I've used just kill or suspend the offending task/thread.


    Oh, I never meant to dispute that. I just saw "can't be done". If he
    meant "can't be done portably", then I agree.
    Joshua Maurice, Apr 26, 2011
    #13
    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. Steve Franks
    Replies:
    2
    Views:
    1,242
    Steve Franks
    Jun 10, 2004
  2. Tee
    Replies:
    3
    Views:
    7,777
    Herfried K. Wagner [MVP]
    Jun 23, 2004
  3. Marc

    noexcept

    Marc, Apr 27, 2011, in forum: C++
    Replies:
    2
    Views:
    475
  4. restor

    Using noexcept in C++0x

    restor, Jun 21, 2011, in forum: C++
    Replies:
    1
    Views:
    390
    Balog Pal
    Jun 22, 2011
  5. Eric Danstron

    Are there ANY good forums out there anymore???

    Eric Danstron, Sep 21, 2005, in forum: ASP General
    Replies:
    1
    Views:
    139
    Immediacy
    Sep 22, 2005
Loading...

Share This Page