locale and static

D

daniele

Why the following code doesn't work? It prints the date using the
default locale instead of mine.
(compiled with Visual C++ 2008)

Thanks.
Daniele


#include <iostream>
#include <sstream>
#include <boost/date_time/posix_time/posix_time.hpp>

using namespace boost::posix_time;

class Log
{
public:
Log();
void Get();
private:
static time_facet* myFacet;
static std::locale myLocale;
std::eek:stringstream os;
};


time_facet* Log::myFacet( new time_facet( "%Y.%m.%d" ) );

std::locale Log::myLocale( std::locale(), myFacet );

Log::Log()
{
#if 0 // this works
time_facet* myfacet( new time_facet( "%Y.%m.%d" ) );
std::locale myLoc( std::locale(), myfacet );
os.imbue( myLoc );
#else // this doesn't work!!!
os.imbue( myLocale );
#endif
}

void Log::Get()
{
ptime t( second_clock::local_time() );
os << t << std::endl;
fprintf( stderr, "%s", os.str().c_str() );
fflush( stderr );
}

int main( int argc, char* argv[] )
{
Log l;
l.Get();

return 0;
}
 
P

Paul Bibbings

daniele said:
Why the following code doesn't work? It prints the date using the
default locale instead of mine.
(compiled with Visual C++ 2008)

Thanks.
Daniele


#include <iostream>
#include <sstream>
#include <boost/date_time/posix_time/posix_time.hpp>

using namespace boost::posix_time;

class Log
{
public:
Log();
void Get();
private:
static time_facet* myFacet;
static std::locale myLocale;
std::eek:stringstream os;
};


time_facet* Log::myFacet( new time_facet( "%Y.%m.%d" ) );

std::locale Log::myLocale( std::locale(), myFacet );

Log::Log()
{
#if 0 // this works
time_facet* myfacet( new time_facet( "%Y.%m.%d" ) );
std::locale myLoc( std::locale(), myfacet );
os.imbue( myLoc );
#else // this doesn't work!!!
os.imbue( myLocale );
#endif
}

void Log::Get()
{
ptime t( second_clock::local_time() );
os << t << std::endl;
fprintf( stderr, "%s", os.str().c_str() );
fflush( stderr );
}

int main( int argc, char* argv[] )
{
Log l;
l.Get();

return 0;
}

Hi Daniele

Well, I can confirm that I get the same results as you have building
your code with Microsoft Visual C++ 2008 Express. I had wanted to think
that it might be something to do with loose guarantees on the
order/timing of static initialization, but that really shouldn't be a
problem here as everything is contained by the single translation unit.

Bumping your code over to gcc-4.4.1 (built with and for the Cygwin 1.7
environment) I don't see the same problems, and your code is well
behaved there. So my only thoughts now is that it's either a problem
with VC, or at a long shot there is some element of undefined or
implementation-defined behaviour in your example, but I really don't
think so. I'm not near a copy of the standard to check it out, but if
my memory serves me well I think that in your example you can expect
that Log::myFacet is initialized before Log::myLocale, and both before
the startup of your main code. My sense, then, is that this should work
as you expect it to.

Regards

Paul Bibbings
 
R

Robert Fendt

Well, I can confirm that I get the same results as you have building
your code with Microsoft Visual C++ 2008 Express. I had wanted to think
that it might be something to do with loose guarantees on the
order/timing of static initialization, but that really shouldn't be a
problem here as everything is contained by the single translation unit.

Bumping your code over to gcc-4.4.1 (built with and for the Cygwin 1.7
environment) I don't see the same problems, and your code is well
behaved there. So my only thoughts now is that it's either a problem
with VC, or at a long shot there is some element of undefined or
implementation-defined behaviour in your example, but I really don't
think so. I'm not near a copy of the standard to check it out, but if
my memory serves me well I think that in your example you can expect
that Log::myFacet is initialized before Log::myLocale, and both before
the startup of your main code. My sense, then, is that this should work
as you expect it to.

I think the difference is most probably the implementation of
std::locale() in VC++, without having a studio available to
check before Monday. Could be that it is inlined during
compilation and MyLocale gets static initialisation, in which
case it would be initialised with myFacet being still 0. I am a
bit fuzzy on the details of static initialisation order, but I
would be surprised if the problem were not somewhere in that
area.

IMHO this would still be a standard violation (since myFacet is
defined before myLocale and clearly gets dynamic initialisation,
this _should_ mean that myLocale is dynamically initialised as
well), but a very subtle one.

Better use a factory function instead of the naked static object
(i.e., the "construct on first use idiom"), that way you should
be able to avoid any problems. See also

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.13

Regards,
Robert
 
D

daniele

I tried the "construct on first use idiom" and it works as expected.
I think you're right: it's a VC++ standard violation.

Thank you
Daniele
 

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

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top