atexit problems and questions....

Discussion in 'C++' started by MathWizard, Jul 27, 2007.

  1. MathWizard

    MathWizard Guest

    Hi all,

    This question relates to an earlier thread I started (static object as
    member of a class).

    I have the following (illustrative) code. Again, I hope to make no typos:

    class A {
    ... //whatever here
    };
    class B {
    ... // omitted ctors, dtor, ....
    A& get_static_A();
    void cleanup();
    };

    A& B::get_static_A()
    {
    static A* A_ptr;

    if (A_ptr == NULL) {
    A_ptr = new A;
    atexit(cleanup);
    }
    return *A_ptr;
    }

    This code is a result of the advice I got in my revious thread. Class B
    needs to share one single copy of class A, and this is the way it should
    all work correctly.

    Problem: my compiler does not like the atexit call, it says: "cannot
    find a match for atexit(void)" I also tried things like
    "atexit(B::cleanup);", but that doesn't help. Any ideas?

    Furthermore, I stumbled on an article at
    http://www.petebecker.com/js/js199904.html

    I cite: "Be very, very careful if you mix |atexit| functions and static
    objects with destructors. The rules are pretty clear: functions
    registered with |atexit| are interleaved with destructors for static
    objects in the reverse order of their registration. If you create a
    static object, then register an |atexit| function, then create another
    static object, the compiler should generate code that invokes the
    destructor for the second object, calls the |atexit| function, then
    invokes the destructor for the first object. If your code relies on this
    sequence being handled correctly it is very likely to crash. If you’re
    concerned about writing portable code (as we are in The Journeyman’s
    Shop) don’t rely on intermixing |atexit| functions with static destructors."

    If I look at the code I wrote above, then I also rely on a strict
    sequence: the cleanup method must be called before the static A is
    destroyed. Comments on this?

    Thanks for any pointers,

    Jeroen
    MathWizard, Jul 27, 2007
    #1
    1. Advertising

  2. MathWizard

    Pete Becker Guest

    On 2007-07-27 15:36:34 -0400, MathWizard <> said:

    >
    > class A {
    > .. //whatever here
    > };
    > class B {
    > .. // omitted ctors, dtor, ....
    > A& get_static_A();
    > void cleanup();
    > };
    >
    > atexit(cleanup);
    >
    > Problem: my compiler does not like the atexit call, it says: "cannot
    > find a match for atexit(void)" I also tried things like
    > "atexit(B::cleanup);", but that doesn't help. Any ideas?


    atexit takes a pointer to an ordinary function, not a pointer to a
    member function. There's no way to pass &B::cleanup to it. After all,
    where is the B object that cleanup should be applied to?

    More generally, though, I'd expect both get_static_A() and cleanup() to
    be static member functions. With that change, the code as written ought
    to work.

    >
    > Furthermore, I stumbled on an article at
    > http://www.petebecker.com/js/js199904.html
    >
    > I cite: "Be very, very careful if you mix |atexit| functions and static
    > objects with destructors. The rules are pretty clear: functions
    > registered with |atexit| are interleaved with destructors for static
    > objects in the reverse order of their registration. If you create a
    > static object, then register an |atexit| function, then create another
    > static object, the compiler should generate code that invokes the
    > destructor for the second object, calls the |atexit| function, then
    > invokes the destructor for the first object. If your code relies on
    > this sequence being handled correctly it is very likely to crash. If
    > you’re concerned about writing portable code (as we are in The
    > Journeyman’s Shop) don’t rely on intermixing |atexit| functions with
    > static destructors."
    >
    > If I look at the code I wrote above, then I also rely on a strict
    > sequence: the cleanup method must be called before the static A is
    > destroyed. Comments on this?
    >
    >


    Well, the text you quote was written in 1999, and back then, there were
    quirky C++ implementations that didn't sequence atexit functions and
    destructors correctly. It's probably better these days, but I haven't
    looked recently. I wouldn't trust it. Especially if there's a chance
    that your code will be used with an older compiler.

    --
    Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
    Standard C++ Library Extensions: a Tutorial and Reference
    (www.petebecker.com/tr1book)
    Pete Becker, Jul 27, 2007
    #2
    1. Advertising

  3. MathWizard wrote:
    > I have the following (illustrative) code. Again, I hope to make no
    > typos:


    Don't type the code into the message. Type it into your code editor,
    compile it, make sure there are no typos to speak of, then copy-and-
    paste it into the message.

    >
    > class A {
    > .. //whatever here
    > };
    > class B {
    > .. // omitted ctors, dtor, ....
    > A& get_static_A();


    Why isn't this 'static'?

    > void cleanup();


    What does it do? Maybe it should be 'static'?

    > };
    >
    > A& B::get_static_A()
    > {
    > static A* A_ptr;
    >
    > if (A_ptr == NULL) {
    > A_ptr = new A;
    > atexit(cleanup);
    > }
    > return *A_ptr;
    > }
    >
    > This code is a result of the advice I got in my revious thread. Class
    > B needs to share one single copy of class A, and this is the way it
    > should all work correctly.
    >
    > Problem: my compiler does not like the atexit call, it says: "cannot
    > find a match for atexit(void)" I also tried things like
    > "atexit(B::cleanup);", but that doesn't help. Any ideas?


    Make 'cleanup' static. Read the FAQ about callbacks and member
    functions.

    > Furthermore, I stumbled on an article at
    > http://www.petebecker.com/js/js199904.html
    >
    > I cite: "[snip - VB] If
    > you’re concerned about writing portable code (as we are in The
    > Journeyman’s Shop) don’t rely on intermixing |atexit| functions with
    > static
    > destructors."
    > If I look at the code I wrote above, then I also rely on a strict
    > sequence: the cleanup method must be called before the static A is
    > destroyed.


    There is no static A in your code. There is a static A*, and there
    is a dynamic A.

    > Comments on this?


    None.

    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, Jul 27, 2007
    #3
  4. MathWizard

    terminator Guest

    On Jul 27, 10:36 pm, MathWizard <> wrote:

    > class B {
    > .. // omitted ctors, dtor, ....
    > A& get_static_A();
    > void cleanup();
    >
    > };
    >
    > A& B::get_static_A()
    > {
    > static A* A_ptr;
    >

    ...
    > atexit(cleanup);



    your functions must be declared as to be 'static'(for the same purpose
    that you declare some objects as 'static'):

    class B {
    .. // omitted ctors, dtor, ....
    static A& get_static_A();
    static void cleanup();

    };

    and if the compiler compligns on 'atexit' again, the try declaring
    'cleanup' with 'cdecl' or '_cdecl' specifiers or some resembling
    stuff.

    regards,
    FM.
    terminator, Jul 28, 2007
    #4
  5. MathWizard

    MathWizard Guest

    Everybody thanks for all the answers. I got everything to work.

    Jeroen
    MathWizard, Jul 29, 2007
    #5
  6. MathWizard wrote:
    > Everybody thanks for all the answers. I got everything to work.


    Right, everybody thanks, but what about you?
    Victor Bazarov, Jul 29, 2007
    #6
  7. MathWizard

    MathWizard Guest

    Victor Bazarov wrote:

    >MathWizard wrote:
    >
    >
    >>Everybody thanks for all the answers. I got everything to work.
    >>
    >>

    >
    >Right, everybody thanks, but what about you?
    >
    >

    I'm afraid I don't understand the question entirely... About me:

    * I got my piece of code to work.
    * These threads point me to aspects of C++ I have to look into further.
    MathWizard, Jul 29, 2007
    #7
  8. On 2007-07-29 19:03, MathWizard wrote:
    > Victor Bazarov wrote:
    >
    >>MathWizard wrote:
    >>
    >>
    >>>Everybody thanks for all the answers. I got everything to work.
    >>>
    >>>

    >>
    >>Right, everybody thanks, but what about you?
    >>
    >>

    > I'm afraid I don't understand the question entirely... About me:
    >
    > * I got my piece of code to work.
    > * These threads point me to aspects of C++ I have to look into further.


    English grammar is a bit off-topic here but anyway:
    What he meant was that the sentence "Everybody thanks for all the
    answers." means that everybody says thanks for the answers. To give it
    the meaning you wanted you need to insert a comma after the word
    'Everyone' so that the sentence reads "Everybody, thanks for all the
    answers."

    --
    Erik Wikström
    =?ISO-8859-1?Q?Erik_Wikstr=F6m?=, Jul 29, 2007
    #8
  9. MathWizard

    BobR Guest

    Victor Bazarov <> wrote in message...
    > MathWizard wrote:
    > > Everybody thanks for all the answers. I got everything to work.

    >
    > Right, everybody thanks, but what about you?


    TV newspeople influence.

    news commercial: "A horrific car crash tonight at eleven!"

    I think, "Well, if they know it's going to happen at eleven, why don't they
    prevent it?".

    > MathWizard *should have* wrote:

    Everybody, thanks for all the answers.

    But then, english/grammer *ain't* my strong point! <G>
    --
    Bob <G> R
    POVrookie
    BobR, Jul 29, 2007
    #9
  10. MathWizard

    MathWizard Guest

    Erik Wikström wrote:

    > On 2007-07-29 19:03, MathWizard wrote:
    >
    >> Victor Bazarov wrote:
    >>
    >>> MathWizard wrote:
    >>>
    >>>
    >>>> Everybody thanks for all the answers. I got everything to work.
    >>>>
    >>>
    >>>
    >>> Right, everybody thanks, but what about you?
    >>>
    >>>

    >> I'm afraid I don't understand the question entirely... About me:
    >>
    >> * I got my piece of code to work.
    >> * These threads point me to aspects of C++ I have to look into
    >> further.

    >
    >
    > English grammar is a bit off-topic here but anyway:
    > What he meant was that the sentence "Everybody thanks for all the
    > answers." means that everybody says thanks for the answers. To give it
    > the meaning you wanted you need to insert a comma after the word
    > 'Everyone' so that the sentence reads "Everybody, thanks for all the
    > answers."
    >

    OK, I just thought there was more behind Victor's question. Not being a
    native speaker sometimes results in sloppy sentences with respect to
    English grammar :) But I meant what you wrote...
    MathWizard, Jul 29, 2007
    #10
    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. Serve Laurijssen

    atexit and global destructors

    Serve Laurijssen, Jan 15, 2004, in forum: C++
    Replies:
    3
    Views:
    6,935
    tom_usenet
    Jan 15, 2004
  2. Andreas Schmitt

    atexit() and DLLs

    Andreas Schmitt, Mar 9, 2007, in forum: C++
    Replies:
    1
    Views:
    691
    =?ISO-8859-1?Q?Erik_Wikstr=F6m?=
    Mar 9, 2007
  3. Laurent Deniau

    exit, atexit and scope

    Laurent Deniau, Nov 15, 2007, in forum: C Programming
    Replies:
    22
    Views:
    807
    Laurent Deniau
    Nov 19, 2007
  4. Darren Dale
    Replies:
    8
    Views:
    570
    Darren Dale
    Mar 6, 2009
  5. Roy Smith

    Some questions about atexit

    Roy Smith, Sep 13, 2012, in forum: Python
    Replies:
    2
    Views:
    181
    Roy Smith
    Sep 13, 2012
Loading...

Share This Page