This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

ODR violation for std::cout etc.


Currently libstdc++ violates ODR:
iostream:     extern ostream cout;  fake_ostream cout;

It assumes that gcc will work fine with this. Apparently it does, for now.
After solving a similar problem in my code using a similar technique - to find out that it does not work for MS VS-2005 - when I had to find a different fix.

The question is, why does GCC has to resolve to such construction-order issue this way?

Idea (which I used):
don't violate ODR in Instead, construct and destroy std::cout two times, in a safe way:

static PreSecondCtor coutPreSecondCtor(std::cout);
ostream std::cout(NULL);
static PostSecondCtor coutPostSecondCtor(coutPreSecodCtor);

When PreSecondCtor saves all relevant data of cout (error bits, state, rdbuf, etc.),
and then calls std::cout.~ostream();
Note that before this point, std::cout has already been constructed by an std::ios::Init,
and we need to avoid double construction.

In PostSecondCtor, restore the state of cout out of the saved data in outPreSecondCtor.

During destruction the order is reversed.

I still have a vague feeling that this solution is also undefined (since we are calling the constructor of std::cout, using placement new, after it had been automatically destroyed by the C++ environment). I don't have the standard near me, so I can't check.

Anyway, even if this is undefined, the situation is arguably better since it does not seem to break whole program compilation (like current implementation might).

What do you think?


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]