From Bugzilla Helper: User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:0.9.9) Gecko/20020311 Description of problem: If the line '#define TWO_INSERTERS' is commented out, the program compiles without warnings (using -W -Wall) and works as expected, namely writing 'manipulator called' two times. If the program is compiled as is, one obtains a warning during compile (which tells us that the compiler does not use the stream inserter we intend to) and the program writes 'manipulator called' only once. gcc 2.96/2.95.3 always compiles without warnings and calls the stream manipulator twice. Also does the Borland Compiler 5.5.1 and Comeau 4.3Beta2. Version-Release number of selected component (if applicable): How reproducible: Always Steps to Reproduce: 1. g++3 -W -Wall manip.cpp 2. 3. Actual Results: During compile: manip.cpp: In function `void ns::f()': manip.cpp:28: warning: the address of `void ns::manipulator(std::ostringstream&)', will always be `true' Expected Results: No warnings and the output 'manipulator called' two times. Additional info: #include <iostream> #include <sstream> #define TWO_INSERTERS void operator<<(std::ostream& s, void (*f)(std::ostringstream&)) { f(dynamic_cast<std::ostringstream&>(s)); } namespace ns { void manipulator(std::ostringstream&) { std::cout << "manipulator called" << std::endl; } #ifdef TWO_INSERTERS std::ostream& operator<<(std::ostream& s, int) { return s; } #endif void f() { std::ostringstream s; s << ns::manipulator; } } // namespace int main() { std::ostringstream s; s << ns::manipulator; ns::f(); return 0; }
According to Jason Merrill this is correct. The big difference between g++ 2.9x and 3.x is honoring of std namespace which changes things a lot for this testcase. If you have an inserter in the ns namespace, then standard bool inserter is chosen.