std::exit Ambiguity?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • JKop

    std::exit Ambiguity?

    An excerpt from the Standard:


    4 Calling the function
    void exit(int);
    declared in <cstdlib> (18.3) terminates the program without leaving the
    current block and hence without
    destroying any objects with automatic storage duration (12.4). If exit is
    called to end a program during
    the destruction of an object with static storage duration, the program has
    undefined behavior.


    Now take the following code:


    #include <cstdlib>
    #include <iostream>

    class Blah
    {
    public:

    ~Blah()
    {
    std::cout << "\nBlah's Destructor!\n";
    }
    };


    int main()
    {
    Blah blah;

    { exit(0); }
    }


    I myself would've thought that blah's destructor *would* have been called...
    after all, its scope isn't that of "the current block".


    Thoughts?


    -JKop
  • JKop

    #2
    Re: std::exit Ambiguity?

    The destructor doesn't get called in the following either:

    #include <cstdlib>
    #include <iostream>

    void Cow()
    {
    exit(0);
    }

    int main()
    {
    Blah blah;

    Cow();
    }

    Comment

    • John Harrison

      #3
      Re: std::exit Ambiguity?


      "JKop" <NULL@NULL.NULL > wrote in message
      news:QxT5d.3221 5$Z14.10989@new s.indigo.ie...[color=blue]
      > An excerpt from the Standard:
      >
      >
      > 4 Calling the function
      > void exit(int);
      > declared in <cstdlib> (18.3) terminates the program without leaving the
      > current block and hence without
      > destroying any objects with automatic storage duration (12.4). If exit is
      > called to end a program during
      > the destruction of an object with static storage duration, the program has
      > undefined behavior.
      >
      >
      > Now take the following code:
      >
      >
      > #include <cstdlib>
      > #include <iostream>
      >
      > class Blah
      > {
      > public:
      >
      > ~Blah()
      > {
      > std::cout << "\nBlah's Destructor!\n";
      > }
      > };
      >
      >
      > int main()
      > {
      > Blah blah;
      >
      > { exit(0); }
      > }
      >
      >
      > I myself would've thought that blah's destructor *would* have been[/color]
      called...[color=blue]
      > after all, its scope isn't that of "the current block".
      >
      >
      > Thoughts?
      >[/color]

      I think you're misreading the standard. It doesn't say that destruction
      depends upon whether an object is in the current block or not. It says that
      destructors for automatic objects are not called BECAUSE the current block
      isn't left. In other words no destructors for automatic objects will be
      called, period.

      If you want to end a program and have automatic object destructors called
      then throw an exception.

      john


      Comment

      • NULL@NULL.NULL

        #4
        Re: std::exit Ambiguity?

        >> 4 Calling the function[color=blue][color=green]
        >> void exit(int);
        >> declared in <cstdlib> (18.3) terminates the program without leaving
        >> the current block and hence without
        >> destroying any objects with automatic storage duration (12.4). If exit
        >> is called to end a program during
        >> the destruction of an object with static storage duration, the program
        >> has undefined behavior.
        >>[/color]
        >
        > I think you're misreading the standard. It doesn't say that destruction
        > depends upon whether an object is in the current block or not. It says
        > that destructors for automatic objects are not called BECAUSE the
        > current block isn't left. In other words no destructors for automatic
        > objects will be called, period.[/color]

        Hmm... yeah... I suppose... but I'd prefer if the Standard were more
        explicit. For example:

        without destroying any and all objects with automatic storage, including
        those defined in other blocks.
        [color=blue]
        > If you want to end a program and have automatic object destructors
        > called then throw an exception.
        >
        > john[/color]


        Helpful as ever, thanks!

        You mean throw an exception and not catch in?

        What I'm doing is calling a function from main. I want this function to have
        the "power" to end the program.


        As in:


        void SomeFunc()
        {
        //something goes wrong

        throw int();
        }


        int main()
        {
        SomeFunc();
        }


        What happens when an exception isn't caught... I take it there's a certain
        "std::" function called, yeah?

        But then again, seeing as how there's no destructors to be called in my code
        above, is there anything... wrong... with calling exit? And let's say for
        instance that you have an "std::strin g" object with automatic storage, if
        you call exit() are you invoking UB by not having its destructor called? And
        even though the destructor isn't called, is the memory still deallocated for
        the object?


        -JKop

        Comment

        • John Harrison

          #5
          Re: std::exit Ambiguity?


          <NULL@NULL.NULL > wrote in message
          news:aXT5d.3221 7$Z14.10977@new s.indigo.ie...[color=blue][color=green][color=darkred]
          > >> 4 Calling the function
          > >> void exit(int);
          > >> declared in <cstdlib> (18.3) terminates the program without leaving
          > >> the current block and hence without
          > >> destroying any objects with automatic storage duration (12.4). If exit
          > >> is called to end a program during
          > >> the destruction of an object with static storage duration, the program
          > >> has undefined behavior.
          > >>[/color]
          > >
          > > I think you're misreading the standard. It doesn't say that destruction
          > > depends upon whether an object is in the current block or not. It says
          > > that destructors for automatic objects are not called BECAUSE the
          > > current block isn't left. In other words no destructors for automatic
          > > objects will be called, period.[/color]
          >
          > Hmm... yeah... I suppose... but I'd prefer if the Standard were more
          > explicit. For example:
          >
          > without destroying any and all objects with automatic storage, including
          > those defined in other blocks.
          >[color=green]
          > > If you want to end a program and have automatic object destructors
          > > called then throw an exception.
          > >
          > > john[/color]
          >
          >
          > Helpful as ever, thanks!
          >
          > You mean throw an exception and not catch in?
          >
          > What I'm doing is calling a function from main. I want this function to[/color]
          have[color=blue]
          > the "power" to end the program.
          >
          >
          > As in:
          >
          >
          > void SomeFunc()
          > {
          > //something goes wrong
          >
          > throw int();
          > }
          >
          >
          > int main()
          > {
          > SomeFunc();
          > }
          >
          >
          > What happens when an exception isn't caught... I take it there's a certain
          > "std::" function called, yeah?[/color]

          Not sure, std::terminate I think, look it up. But in practice it might be
          better to do this

          int main()
          {
          try
          {
          SomeFunc();
          }
          catch (...)
          {
          }
          }

          just to make sure that you exit main in the normal way. This should ensure
          that global objects get destructed too.
          [color=blue]
          >
          > But then again, seeing as how there's no destructors to be called in my co[/color]
          de[color=blue]
          > above, is there anything... wrong... with calling exit? And let's say for
          > instance that you have an "std::strin g" object with automatic storage, if
          > you call exit() are you invoking UB by not having its destructor called?[/color]

          No I don't think so.
          [color=blue]
          > And
          > even though the destructor isn't called, is the memory still deallocated[/color]
          for[color=blue]
          > the object?
          >[/color]

          That's system dependent I think. Most O/S will return all allocated memory
          to the system upon program exit (after all whoever heard of a program that
          didn't leak memory). Windows and Unix both do this.

          john


          Comment

          • Jacek Dziedzic

            #6
            Re: std::exit Ambiguity?

            NULL@NULL.NULL wrote:[color=blue]
            >
            > What I'm doing is calling a function from main. I want this function to have
            > the "power" to end the program.
            >
            >
            > As in:
            >
            >
            > void SomeFunc()
            > {
            > //something goes wrong
            >
            > throw int();
            > }
            >
            >
            > int main()
            > {
            > SomeFunc();
            > }
            >
            >
            > What happens when an exception isn't caught... I take it there's a certain
            > "std::" function called, yeah?
            >
            > But then again, seeing as how there's no destructors to be called in my code
            > above, is there anything... wrong... with calling exit? And let's say for
            > instance that you have an "std::strin g" object with automatic storage, if
            > you call exit() are you invoking UB by not having its destructor called? And
            > even though the destructor isn't called, is the memory still deallocated for
            > the object?[/color]

            The memory will be eventually freed by the operating system (hopefully).

            You could always

            class ExcTerminate {};

            void SomeFunc() {
            throw ExcTerminate();
            }

            int main() {
            // ...
            try {
            // ...
            }
            catch(ExcTermin ate) {
            return 0;
            }
            // ...
            }

            - J.

            Comment

            • JKop

              #7
              Re: std::exit Ambiguity?

              > class ExcTerminate {};[color=blue]
              >
              > void SomeFunc() {
              > throw ExcTerminate();
              > }
              >
              > int main() {
              > // ...
              > try {
              > // ...
              > }
              > catch(ExcTermin ate) {
              > return 0;
              > }
              > // ...
              > }[/color]


              You're a mind reader - I just did that 5 minutes ago!


              -JKop

              Comment

              • Vyacheslav Kononenko

                #8
                Re: std::exit Ambiguity?

                How about:
                struct ExcTerminate {
                int code;
                ExcTerminate(in t retcode) : code(retcode){}
                };

                int main()
                {
                try {
                ...
                }
                catch(ExcTermin ate exc){
                return exc.code;
                }
                ...
                }

                Regards,
                Vyacheslav

                "JKop" <NULL@NULL.NULL > wrote in message
                news:IvU5d.3222 5$Z14.10983@new s.indigo.ie...[color=blue][color=green]
                > > class ExcTerminate {};
                > >
                > > void SomeFunc() {
                > > throw ExcTerminate();
                > > }
                > >
                > > int main() {
                > > // ...
                > > try {
                > > // ...
                > > }
                > > catch(ExcTermin ate) {
                > > return 0;
                > > }
                > > // ...
                > > }[/color]
                >
                >
                > You're a mind reader - I just did that 5 minutes ago!
                >
                >
                > -JKop[/color]


                Comment

                • JKop

                  #9
                  Re: std::exit Ambiguity?

                  [color=blue]
                  > struct ExcTerminate {
                  > int code;
                  > ExcTerminate(in t retcode) : code(retcode){}
                  > };
                  >
                  > int main()
                  > {
                  > try {
                  > ...
                  > }
                  > catch(ExcTermin ate exc){
                  > return exc.code;
                  > }
                  > ...
                  > }[/color]


                  Even better!


                  -JKop

                  Comment

                  • Rolf Magnus

                    #10
                    Re: std::exit Ambiguity?

                    NULL@NULL.NULL wrote:
                    [color=blue][color=green][color=darkred]
                    >>> 4 Calling the function
                    >>> void exit(int);
                    >>> declared in <cstdlib> (18.3) terminates the program without leaving
                    >>> the current block and hence without
                    >>> destroying any objects with automatic storage duration (12.4). If exit
                    >>> is called to end a program during
                    >>> the destruction of an object with static storage duration, the program
                    >>> has undefined behavior.
                    >>>[/color]
                    >>
                    >> I think you're misreading the standard. It doesn't say that destruction
                    >> depends upon whether an object is in the current block or not. It says
                    >> that destructors for automatic objects are not called BECAUSE the
                    >> current block isn't left. In other words no destructors for automatic
                    >> objects will be called, period.[/color]
                    >
                    > Hmm... yeah... I suppose... but I'd prefer if the Standard were more
                    > explicit. For example:
                    >
                    > without destroying any and all objects with automatic storage, including
                    > those defined in other blocks.[/color]

                    That's what it says. You quoted it yourself: "... and hence without
                    destroying any objects with automatic storage duration". Nothing about
                    objects within the current block, just "any objects".
                    [color=blue]
                    > You mean throw an exception and not catch in?
                    >
                    > What I'm doing is calling a function from main. I want this function to
                    > have the "power" to end the program.
                    >
                    >
                    > As in:
                    >
                    >
                    > void SomeFunc()
                    > {
                    > //something goes wrong
                    >
                    > throw int();
                    > }
                    >
                    >
                    > int main()
                    > {
                    > SomeFunc();
                    > }
                    >
                    >
                    > What happens when an exception isn't caught... I take it there's a certain
                    > "std::" function called, yeah?
                    >
                    > But then again, seeing as how there's no destructors to be called in my
                    > code above, is there anything... wrong... with calling exit? And let's say
                    > for instance that you have an "std::strin g" object with automatic storage,
                    > if you call exit() are you invoking UB by not having its destructor
                    > called? And even though the destructor isn't called, is the memory still
                    > deallocated for the object?[/color]

                    Depends on the OS, but usually, the memory is freed. But think about other
                    things, like a file which buffered data has to be written to before being
                    closed or a database connection that needs to be shut down properly.

                    Comment

                    • Ron Natalie

                      #11
                      Re: std::exit Ambiguity?


                      <NULL@NULL.NULL > wrote in message news:aXT5d.3221 7$Z14.10977@new s.indigo.ie...[color=blue]
                      > What I'm doing is calling a function from main. I want this function to have
                      > the "power" to end the program.
                      >[/color]

                      No you have to catch it in main. It's unspecified if the stack is unwound on the way to
                      terminate.

                      Comment

                      Working...