Topic: Standard question on global iostream objects


Author: James.Kanze@dresdner-bank.com
Date: 2000/11/07
Raw View
In article <58VL5.927$dB6.41728@bgtnsc05-news.ops.worldnet.att.net>,
  "Ron Ruble" <raffles2@att.net> wrote:
> A poster in comp.lang.c++.moderated had a question
> about some odd behavior in VC. We answered his
> questions on *why* the behavior occurs, but there's
> some question about whether it is in violation of the
> standard.

> I couldn't find anything dealing with it specifically.

> -----------------------------------------------------------

> #include <fstream>
> using namespace std;

> class Logger
> {
> public:
> Logger(char* pFN):pFileName(pFN) {}
> ~Logger() {ofstream aFile(pFileName); aFile<<1;}
> private:
> char* pFileName;
> };

> static Logger log2("log2.txt");

> int main()
> {
> Logger log1("log1.txt");
> return 0;
> }

> -------------------------------------------------------

> The gist of it is this: VC defers initialization of certain objects
> used by the stream classes until their first use.

> MS documents this behavior.

> The Logger object in main is destroyed at the closing brace creating
> the ofstream object (and initializing the stream objects). But since
> they were created after the static global log2 object, they are
> cleaned up first.

> When log2 is destroyed, VC raises an Access Violation.

> Now the standard requires the predefined objects (cin, cout, etc)
> remain usable by any objects even in their destructors, but I can't
> find a requirement that user- defined stream objects be usable, nor
> a specific exemption that says this is allowable.

A user defined stream object must be usable until its destruction.  If
the object is static, of course, and one wants to use it in the
destructors of static objects, one must worry about the order of
destruction.  Otherwise, however, you should be safe.

> Section 3.6.3 indicates the committee thought about this sort of
> thing, but refers specifically to functions containing local static
> objects, rather than globals.

> P. J. Plauger wrote in his Standard C++ column about some of the
> tricks used to ensure that the standard stream objects are
> constructed first and remain usable through program termination. To
> me, this sort of indicates that the committee decided *not* to
> guarantee that user defined stream objects remain usable (rather
> than an being omission).

For user defined objects, it's up to the user.  He's free to use the
same tricks as the implementation uses:-).

But this isn't an issue in the example program.  The user declares a
*local* variable, with automatic lifetime.  So issues concerning
static variables don't enter in question.

> Comments? Relevant parts of the standard I missed?

I'd say that the burden of proof is on the other foot.  There is
definitly nothing in the standard which generally forbids declaring
local variables in a destructor, even if the destructor is called for
a static object.  So unless there is some special wording for
ofstream, it's legal too.

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Ron Ruble" <raffles2@att.net>
Date: Wed, 1 Nov 2000 16:46:07 GMT
Raw View
A poster in comp.lang.c++.moderated had a question
about some odd behavior in VC. We answered his
questions on *why* the behavior occurs, but there's
some question about whether it is in violation of the
standard.

I couldn't find anything dealing with it specifically.

-----------------------------------------------------------

#include <fstream>
using namespace std;

class Logger
{
public:
Logger(char* pFN):pFileName(pFN) {}
~Logger() {ofstream aFile(pFileName); aFile<<1;}
private:
char* pFileName;
};

static Logger log2("log2.txt");

int main()
{
Logger log1("log1.txt");
return 0;
}

-------------------------------------------------------

The gist of it is this: VC defers initialization of certain
objects used by the stream classes until their first use.

MS documents this behavior.

The Logger object in main is destroyed at the closing
brace creating the ofstream object (and initializing the
stream objects). But since they were created after the
static global log2 object, they are cleaned up first.

When log2 is destroyed, VC raises an Access Violation.

Now the standard requires the predefined objects (cin,
cout, etc) remain usable by any objects even in their
destructors, but I can't find a requirement that user-
defined stream objects be usable, nor a specific
exemption that says this is allowable.

Section 3.6.3 indicates the committee thought about
this sort of thing, but refers specifically to functions
containing local static objects, rather than globals.

P. J. Plauger wrote in his Standard C++ column about
some of the tricks used to ensure that the standard
stream objects are constructed first and remain usable
through program termination. To me, this sort of indicates
that the committee decided *not* to guarantee that
user defined stream objects remain usable (rather than
an being omission).

Comments? Relevant parts of the standard I missed?


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]