This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
ODR violation for std::cout etc.
- From: Michael Veksler <mveksler at tx dot technion dot ac dot il>
- To: gcc at gcc dot gnu dot org
- Date: Tue, 10 Jul 2007 19:44:19 +0300
- Subject: ODR violation for std::cout etc.
Hello,
Currently libstdc++ violates ODR:
iostream: extern ostream cout;
global_io.cc: 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 global_io.cc. 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?
Michael