atexit problems and questions....

M

MathWizard

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
 
P

Pete Becker

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.
 
V

Victor Bazarov

MathWizard said:
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
 
T

terminator

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.
 
M

MathWizard

Victor said:
MathWizard wrote:



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.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

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."
 
B

BobR

Victor Bazarov said:
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>
 
M

MathWizard

Erik said:
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...
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,585
Members
45,080
Latest member
mikkipirss

Latest Threads

Top