 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
kanze@gabi-soft.fr Guest
|
Posted: Thu Jun 26, 2003 7:11 pm Post subject: Re: Destructor not called when object is declared globally |
|
|
Francis Glassborow <francis.glassborow (AT) ntlworld (DOT) com> wrote
| Quote: | In message <eb906752.0306232126.56eaf816 (AT) posting (DOT) google.com>, Sarang
Aravamuthan <sarang_rajan (AT) yahoo (DOT) com> writes
I'm observing a rather strange phenomenon with the following piece of
code:
/* This seems to work only when redirected to a file, for eg. through
sometests > filename
Also it works only when X is declared the way it is but not when
declared
starter X();
*/
#include <iostream
using namespace std;
class starter {
public:
starter() {cout << "Initialize n";}
~starter() {cout << "Clean upn"; };
};
starter X;
void main()
returns an int not a void
{
cout << "in main()n";
}
When I compile and run this code in debug mode or in command line, I
get the following output (i.e. the destructor is not invoked).
Initialize
in main()
Well your code (after correcting the return type of main()) ran
exactly the same in both cases when I used G++. I suspect that your
environment (and you do not say what that is) is ignoring output after
exit from main() but the output is still generated as is shown by the
redirection.
|
While I think you're right in this case, it is worth pointing out that
cout is only guaranteed to be constructed after the first instance of
ios::Init has been constructed (or main has been entered, whichever
comes first). As it happens, g++ (like many compilers) declares a
static instance of ios::Init in
transition from the classical iostreams (which required this) easier.
But the standard doesn't requirer it; I'd add a definition of an
ios::Init object somewhere to be sure (probably as a static variable in
the constructor).
The other point is that the destructor of the last ios::Init object will
call flush on the stream. Again, if there isn't one, no one calls
flush, and the output doesn't get to the OS. (The standard stream
objects are never destructed, so the data won't get flushed there
either.) The easiest way to be sure here is to use std::endl instead of
'n' -- I'd say that this is a generally preferable solution except when
you explicitly know that there will be a batch of output (or a close or
program termination) immediately following. Basically, std::endl always
works, whereas 'n' doesn't.
--
James Kanze GABI Software
mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter
Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, Tél. : +33 (0)1 30 23 45
16
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
MiniDisc_2k2 Guest
|
Posted: Thu Jun 26, 2003 7:42 pm Post subject: Re: Destructor not called when object is declared globally |
|
|
Try flushing the buffer (note I replaced your n's with endl's because
that'll flush the buffer). If you don't want to end the line but need to
flush the buffer (for future reference), you need to make a call to
cout.flush().
<snip>
| Quote: | class starter {
public:
starter() {cout << "Initialize " << endl;} |
~starter() {cout << "Clean up" << endl; };
| Quote: | };
starter X;
void main()
{
cout << "in main()" << endl;
}
When I compile and run this code in debug mode or in command line, I
get the following output (i.e. the destructor is not invoked).
Initialize
in main()
|
That's because the last line is not flushed. It remains in the buffer
while
the program ends.
| Quote: |
However, if I redirect the output to a file through "sometest.exe
outfile", outfile contains
Initialize
in main()
Clean up
|
That's because files do not need to be flushed.
| Quote: |
as one would expect. Moreover, if the class object is declared as
starter X();
then neither the constructor, nor the destructor is invoked in any way
I generate the output, i.e. the output is just the string "in main()".
|
Not quite sure why that is, but perhaps it's because of doing something
like
this:
#include
void a();
void b();
int main()
{
return (0);
}
void a() { b(); }
void b() { cout << "in b()"; }
Nothing would be displayed, even though you have a call to b(). Just
like
the constructor. It's like you're never calling it, because you never
actually reach that code.
| Quote: |
Can someone shed any insight on why the program exits without calling
the destructor--or is this a problem with my compiler?
|
Neither. The destructor is called and your compiler is fine.
-- MiniDisc_2k2
To reply, replace nospam.com with cox dot net
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
MiniDisc_2k2 Guest
|
Posted: Thu Jun 26, 2003 7:43 pm Post subject: Re: Destructor not called when object is declared globally |
|
|
Try flushing the buffer (note I replaced your n's with endl's because
that'll flush the buffer). If you don't want to end the line but need to
flush the buffer (for future reference), you need to make a call to
cout.flush().
<snip>
| Quote: | class starter {
public:
starter() {cout << "Initialize " << endl;} |
~starter() {cout << "Clean up" << endl; };
| Quote: | };
starter X;
void main()
{
cout << "in main()" << endl;
}
When I compile and run this code in debug mode or in command line, I
get the following output (i.e. the destructor is not invoked).
Initialize
in main()
|
That's because the last line is not flushed. It remains in the buffer
while
the program ends.
| Quote: |
However, if I redirect the output to a file through "sometest.exe
outfile", outfile contains
Initialize
in main()
Clean up
|
That's because files do not need to be flushed.
| Quote: |
as one would expect. Moreover, if the class object is declared as
starter X();
then neither the constructor, nor the destructor is invoked in any way
I generate the output, i.e. the output is just the string "in main()".
|
Not quite sure why that is, but perhaps it's because of doing something
like
this:
#include
void a();
void b();
int main()
{
return (0);
}
void a() { b(); }
void b() { cout << "in b()"; }
Nothing would be displayed, even though you have a call to b(). Just
like
the constructor. It's like you're never calling it, because you never
actually reach that code.
| Quote: |
Can someone shed any insight on why the program exits without calling
the destructor--or is this a problem with my compiler?
|
Neither. The destructor is called and your compiler is fine.
-- MiniDisc_2k2
To reply, replace nospam.com with cox dot net
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Fri Jun 27, 2003 12:24 am Post subject: Re: Destructor not called when object is declared globally |
|
|
In message <30869baf.0306240556.12847b (AT) posting (DOT) google.com>, David
Cattarin <dittoC (AT) ix (DOT) netcom.com> writes
| Quote: | I suspect the destructor is getting called, but I think your iostreams
implementation might have a flushing problem when the streams are
destructed. I would have thought that the standard requires cout to
flush when it is destroyed, but that might not be the case.
|
Actually the standard requires that cout is not destroyed :-)
--
ACCU Spring Conference 2003 April 2-5
The Conference you should not have missed
ACCU Spring Conference 2004 Late April
Francis Glassborow ACCU
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Tony Guest
|
Posted: Fri Jun 27, 2003 4:50 pm Post subject: Re: Destructor not called when object is declared globally |
|
|
| Quote: |
However, if I redirect the output to a file through "sometest.exe
outfile", outfile contains
Initialize
in main()
Clean up
That's because files do not need to be flushed.
|
I tried this in MS VC++ 6.0.
I am not sure if this is a flush problem. Even I added "endl" to the
dtor.
The print in dtor is not done. If the output is redirecting to a file.
The
print is correct just as it is expected.
Then I tried it in SGI machine (But I am not sure what compiler I am
using - .
The print in dtor is done correctly even without "endl".
Tony
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
David Cattarin Guest
|
Posted: Fri Jun 27, 2003 8:15 pm Post subject: Re: Destructor not called when object is declared globally |
|
|
Francis Glassborow <francis.glassborow (AT) ntlworld (DOT) com> wrote
| Quote: | In message <30869baf.0306240556.12847b (AT) posting (DOT) google.com>, David
Cattarin <dittoC (AT) ix (DOT) netcom.com> writes
I suspect the destructor is getting called, but I think your
iostreams
implementation might have a flushing problem when the streams are
destructed. I would have thought that the standard requires cout to
flush when it is destroyed, but that might not be the case.
Actually the standard requires that cout is not destroyed
|
Really? Where does it say that? Now I'm confused. I thought cout was a
global static object and would be destroyed on program termination. I
also thought that note 209 might imply that it got flushed at this
point (though I know it says underlying C stream).
Dave
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Sat Jun 28, 2003 3:41 pm Post subject: Re: Destructor not called when object is declared globally |
|
|
In message <30869baf.0306270733.75c7f444 (AT) posting (DOT) google.com>, David
Cattarin <dittoC (AT) ix (DOT) netcom.com> writes
| Quote: | Really? Where does it say that? Now I'm confused. I thought cout was a
global static object and would be destroyed on program termination. I
also thought that note 209 might imply that it got flushed at this
point (though I know it says underlying C stream).
|
See 27.3 para 2 last sentence:
The objects are not destroyed during program execution.
And if you look at the section where footnote 209 is you will see that
the dtors for static objects are called before the C streams are closed.
Nothing about dtors being called latter and calling a dtor for cin, cout
etc. without closing the stream to which it is attached might cause some
problems.
--
ACCU Spring Conference 2003 April 2-5
The Conference you should not have missed
ACCU Spring Conference 2004 Late April
Francis Glassborow ACCU
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Mon Jun 30, 2003 10:34 am Post subject: Re: Destructor not called when object is declared globally |
|
|
[email]tongru_huo (AT) yahoo (DOT) com[/email] (Tony) wrote in message
news:<1f87458d.0306270549.46a18217 (AT) posting (DOT) google.com>...
| Quote: | However, if I redirect the output to a file through "sometest.exe
outfile", outfile contains
Initialize
in main()
Clean up
That's because files do not need to be flushed.
I tried this in MS VC++ 6.0. I am not sure if this is a flush problem.
Even I added "endl" to the dtor. The print in dtor is not done. If the
output is redirecting to a file. The print is correct just as it is
expected. Then I tried it in SGI machine (But I am not sure what
compiler I am using - . The print in dtor is done correctly even
without "endl".
|
Formally, unless you've done something to ensure that cout was
constructed before the print in the constructor, you have undefined
behavior. Practically, I don't think that this is your problem -- the
most likely symptom if the code wasn't going to work would be a core
dump before entering main.
If the print in the destructor doesn't appear even when endl is used,
the compiler is not conformant. In practice, with most of the
implementations I've seen, the print in the destructor will appear even
without endl, but this is not guaranteed, *unless* you have defined an
instance of std::ios::Init before your static object in the same file.
In practice, if no instance of std::ios::Init has been constructed
before your constructor executes, you will almost surely core dump, and
if an instance has been constructed with static lifetime, you don't need
the endl.
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, Tél. : +33 (0)1 30 23 45 16
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
David Cattarin Guest
|
Posted: Mon Jun 30, 2003 6:49 pm Post subject: Re: Destructor not called when object is declared globally |
|
|
Francis Glassborow <francis.glassborow (AT) ntlworld (DOT) com> wrote
| Quote: | In message <30869baf.0306270733.75c7f444 (AT) posting (DOT) google.com>, David
Cattarin <dittoC (AT) ix (DOT) netcom.com> writes
Really? Where does it say that? Now I'm confused. I thought cout was a
global static object and would be destroyed on program termination. I
also thought that note 209 might imply that it got flushed at this
point (though I know it says underlying C stream).
See 27.3 para 2 last sentence:
The objects are not destroyed during program execution.
|
Sure, but on program termination, wouldn't you agree that they are
destroyed?
| Quote: | And if you look at the section where footnote 209 is you will see that
the dtors for static objects are called before the C streams are closed.
Nothing about dtors being called latter and calling a dtor for cin, cout
etc. without closing the stream to which it is attached might cause some
problems.
|
I realize that "Standard C++ IOStreams & Locales" is not the standard,
but it gave me the impression that cout is associated with stdout. I
would have thought, though I can't see it guaranteed in the standard,
that when cout is destroyed, its data is written to stdout which is
guaranteed to be flushed before termination.
What am I missing?
Dave
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Tue Jul 01, 2003 7:32 pm Post subject: Re: Destructor not called when object is declared globally |
|
|
[email]dittoC (AT) ix (DOT) netcom.com[/email] (David Cattarin) wrote in message
news:<30869baf.0306300657.49f2427a (AT) posting (DOT) google.com>...
| Quote: | Francis Glassborow <francis.glassborow (AT) ntlworld (DOT) com> wrote in message
news:<Uo2w+nDFlMicrosoft+EwZ6 (AT) robinton (DOT) demon.co.uk>...
In message <30869baf.0306270733.75c7f444 (AT) posting (DOT) google.com>, David
Cattarin <dittoC (AT) ix (DOT) netcom.com> writes
Really? Where does it say that? Now I'm confused. I thought cout
was a global static object and would be destroyed on program
termination. I also thought that note 209 might imply that it got
flushed at this point (though I know it says underlying C stream).
See 27.3 para 2 last sentence:
The objects are not destroyed during program execution.
Sure, but on program termination, wouldn't you agree that they are
destroyed?
|
The standard says no. In practice, I guess it depends on your
definition of "destroyed", the destructor isn't called, but of course,
they are present in the process memory space, and once the process
terminates, that memory space is deallocated.
The important thing, I guess, is that there is no way a conforming C++
program can tell that they have disappeared.
| Quote: | And if you look at the section where footnote 209 is you will see
that the dtors for static objects are called before the C streams
are closed.
Nothing about dtors being called latter and calling a dtor for cin,
cout |
| Quote: | etc. without closing the stream to which it is attached might cause
some problems.
I realize that "Standard C++ IOStreams & Locales" is not the standard,
but it gave me the impression that cout is associated with stdout. I
would have thought, though I can't see it guaranteed in the standard,
that when cout is destroyed, its data is written to stdout which is
guaranteed to be flushed before termination.
|
That would be true, except that in the sense you are using the word here
(that of the C++ standard), cout is never destroyed.
--
James Kanze GABI Software
mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/
http://www.gabi-soft.fr
Beratung in objektorientierter
Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, Tél. : +33 (0)1 30 23 45
16
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
David Cattarin Guest
|
Posted: Wed Jul 02, 2003 10:09 pm Post subject: Re: Destructor not called when object is declared globally |
|
|
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote in message news:<d6652001.0307010039.7592aeb (AT) posting (DOT) google.com>...
| Quote: | dittoC (AT) ix (DOT) netcom.com (David Cattarin) wrote in message
news:<30869baf.0306300657.49f2427a (AT) posting (DOT) google.com>...
Francis Glassborow <francis.glassborow (AT) ntlworld (DOT) com> wrote in message
news:<Uo2w+nDFlMicrosoft+EwZ6 (AT) robinton (DOT) demon.co.uk>...
In message <30869baf.0306270733.75c7f444 (AT) posting (DOT) google.com>, David
Cattarin <dittoC (AT) ix (DOT) netcom.com> writes
Really? Where does it say that? Now I'm confused. I thought cout
was a global static object and would be destroyed on program
termination. I also thought that note 209 might imply that it got
flushed at this point (though I know it says underlying C stream).
See 27.3 para 2 last sentence:
The objects are not destroyed during program execution.
Sure, but on program termination, wouldn't you agree that they are
destroyed?
The standard says no. In practice, I guess it depends on your
definition of "destroyed", the destructor isn't called, but of course,
they are present in the process memory space, and once the process
terminates, that memory space is deallocated.
The important thing, I guess, is that there is no way a conforming C++
program can tell that they have disappeared.
[snip] |
I think my problem was that I was distinguishing between program
execution and program termination. After going back and rereading the
long definition of program execution (1.9), I can see that it includes
program termination. So, yep, the standard definitely says (27.3) that
cout et al are not destroyed.
Thanks,
Dave
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|