Log File Program: problems btw compilers

T

Thomas Matthews

Is there anything technically wrong with the code below?
I compiled it with g++ 3.3.1 and it executes with no errors.
I compiled it with bcc32 5.6 and it executes with "This
program has performed an illegal operation."
I am running this on Windows 98 platform.

{If not, I'll post this issue to a Borland newsgroup.}

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <streambuf>
using std::filebuf;
using std::streamsize;


class Log_Stream_Buffer : public std::filebuf
{
public:
Log_Stream_Buffer();
Log_Stream_Buffer(const char * filename);
~Log_Stream_Buffer();

void disable_writing(void);
void enable_writing(void);
bool writing_disabled(void) const;
bool writing_enabled(void) const;

protected:
virtual int_type overflow (int_type c);
virtual streamsize xsputn(const char * s, streamsize num);

private:
Log_Stream_Buffer(const
Log_Stream_Buffer& lb);
bool enabled;
};

inline void Log_Stream_Buffer::disable_writing(void)
{
enabled = false;
return;
}

inline void Log_Stream_Buffer::enable_writing(void)
{
enabled = true;
return;
}

inline bool Log_Stream_Buffer::writing_disabled(void) const
{
return !enabled;
}

inline bool Log_Stream_Buffer::writing_enabled(void) const
{
return enabled;
}

Log_Stream_Buffer::Log_Stream_Buffer()
: filebuf(),
enabled(true)
{
open("unnamed_log.txt", ios_base::eek:ut);
}

Log_Stream_Buffer::Log_Stream_Buffer(const char * filename)
: filebuf(),
enabled(true)
{
open(filename, ios_base::eek:ut);
}

Log_Stream_Buffer::~Log_Stream_Buffer()
{
}

filebuf::int_type Log_Stream_Buffer::eek:verflow(int_type c)
{
if (enabled && (c != EOF))
{
filebuf::eek:verflow(c);
}
return c;
}

streamsize Log_Stream_Buffer::xsputn(const char * s, streamsize num)
{
if (enabled)
{
filebuf::xsputn(s, num);
}
return num;
}


class Log_File : public std::eek:stream
{
public:
Log_File();
Log_File(const char * filename);
~Log_File();

Log_Stream_Buffer * close(void);
bool is_paused(void) const;
void pause(void);
void resume(void);
Log_Stream_Buffer * open(const char * filename);

private:
Log_File(const Log_File& lf);
static Log_Stream_Buffer log_buf;
};

inline Log_Stream_Buffer * Log_File::close(void)
{
return dynamic_cast<Log_Stream_Buffer *>(log_buf.close());
}

inline bool Log_File::is_paused(void) const
{
return log_buf.writing_enabled();
}

inline void Log_File::pause(void)
{
log_buf.disable_writing();
return;
}

inline void Log_File::resume(void)
{
log_buf.enable_writing();
return;
}

inline Log_Stream_Buffer * Log_File::eek:pen(const char * filename)
{
return dynamic_cast<Log_Stream_Buffer *>
(log_buf.open(filename, std::ios_base::eek:ut));
}

Log_Stream_Buffer Log_File::log_buf;

Log_File::Log_File()
: ostream(&log_buf)
{
}

Log_File::Log_File(const char * filename)
: ostream(&log_buf)
{
log_buf.open(filename, std::ios_base::eek:ut);
}

Log_File::~Log_File()
{
}


Log_File test_log("log.txt");

int main(void)
{

test_log << "This sentence should be in the file.\n";
test_log.pause();
test_log << "This sentence should NOT be in the file\n";
test_log.resume();
test_log << "The last entry.\n";
test_log.flush();
return EXIT_SUCCESS;
}


When I ran this through the Borland IDE, I got
an exception error in _ios.c in the
basic_ios<>::imbue function:
template <class _CharT, class _Traits>
locale basic_ios<_CharT, _Traits>::imbue(const locale& __loc)
{
locale __tmp = ios_base::imbue(__loc);

if (_M_streambuf)
_M_streambuf->pubimbue(__loc); //***** Error occurs here ******

// no throwing here
this->_M_cached_ctype = __loc._M_get_facet(ctype<char_type>::id) ;
this->_M_cached_numpunct =
__loc._M_get_facet(numpunct<char_type>::id) ;
this->_M_cached_grouping =
((numpunct<char_type>*)_M_cached_numpunct)->grouping() ;
return __tmp;
}

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
J

John Harrison

Thomas Matthews said:
Is there anything technically wrong with the code below?
I compiled it with g++ 3.3.1 and it executes with no errors.
I compiled it with bcc32 5.6 and it executes with "This
program has performed an illegal operation."
I am running this on Windows 98 platform.

[snip]


When I ran this through the Borland IDE, I got
an exception error in _ios.c in the
basic_ios<>::imbue function:
template <class _CharT, class _Traits>
locale basic_ios<_CharT, _Traits>::imbue(const locale& __loc)
{
locale __tmp = ios_base::imbue(__loc);

if (_M_streambuf)
_M_streambuf->pubimbue(__loc); //***** Error occurs here ******

// no throwing here
this->_M_cached_ctype = __loc._M_get_facet(ctype<char_type>::id) ;
this->_M_cached_numpunct =
__loc._M_get_facet(numpunct<char_type>::id) ;
this->_M_cached_grouping =
((numpunct<char_type>*)_M_cached_numpunct)->grouping() ;
return __tmp;
}

I'm using MSVC++ 7.1 and also g++ 3.3.1 in Windows XP

I had to make some minor changes to get it to compile, adding using
std::ios_base and replacing ostream with std::basic_ostream<char> in two
initialiser lists.

Once I did that the program run correctly (but I don't know much about
locales).

john
 
T

Thomas Matthews

Thomas said:
Is there anything technically wrong with the code below?
I compiled it with g++ 3.3.1 and it executes with no errors.
I compiled it with bcc32 5.6 and it executes with "This
program has performed an illegal operation."
I am running this on Windows 98 platform.

{If not, I'll post this issue to a Borland newsgroup.} [snip]


When I ran this through the Borland IDE, I got
an exception error in _ios.c in the
basic_ios<>::imbue function:
template <class _CharT, class _Traits>
locale basic_ios<_CharT, _Traits>::imbue(const locale& __loc)
{
locale __tmp = ios_base::imbue(__loc);

if (_M_streambuf)
_M_streambuf->pubimbue(__loc); //***** Error occurs here ******

// no throwing here
this->_M_cached_ctype = __loc._M_get_facet(ctype<char_type>::id) ;
this->_M_cached_numpunct =
__loc._M_get_facet(numpunct<char_type>::id) ;
this->_M_cached_grouping =
((numpunct<char_type>*)_M_cached_numpunct)->grouping() ;
return __tmp;
}

More details:
If the instance of the Log_File class is moved to
inside a function, there are no problems with the
Borland compiler.

I also tried changing the ostream to basic_ostream<char>
and get the same results.

My next idea is to try making the Log File into a
singleton.


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
J

John Harrison

Thomas Matthews said:
Thomas said:
Is there anything technically wrong with the code below?
I compiled it with g++ 3.3.1 and it executes with no errors.
I compiled it with bcc32 5.6 and it executes with "This
program has performed an illegal operation."
I am running this on Windows 98 platform.

{If not, I'll post this issue to a Borland newsgroup.} [snip]


When I ran this through the Borland IDE, I got
an exception error in _ios.c in the
basic_ios<>::imbue function:
template <class _CharT, class _Traits>
locale basic_ios<_CharT, _Traits>::imbue(const locale& __loc)
{
locale __tmp = ios_base::imbue(__loc);

if (_M_streambuf)
_M_streambuf->pubimbue(__loc); //***** Error occurs here ******

// no throwing here
this->_M_cached_ctype = __loc._M_get_facet(ctype<char_type>::id) ;
this->_M_cached_numpunct =
__loc._M_get_facet(numpunct<char_type>::id) ;
this->_M_cached_grouping =
((numpunct<char_type>*)_M_cached_numpunct)->grouping() ;
return __tmp;
}

More details:
If the instance of the Log_File class is moved to
inside a function, there are no problems with the
Borland compiler.

I'm pretty sure you are running into initialisation order issues. The locale
object has not been initiaised when you first access it.
I also tried changing the ostream to basic_ostream<char>
and get the same results.

My next idea is to try making the Log File into a
singleton.

Try putting the LogFile as a static inside an function. That way it won't be
iniitalised until the function is first called by which time everything else
should have been initialised

static LogFile& the_log_file()
{
static LogFile log_file;
return log_file;
}

int main()
{
the_log_file() << "some message\n";
}

Make the LogFile ctor private and make the_log_file() function a friend of
LogFile. This is one common way to do singletons.

John
 

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,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top