Taking address of std::flush manipulator function not equal to previously stored address in static const variable

StackOverflow https://stackoverflow.com/questions/21164360

Question

I am developing a logger class that overloads the stream insertion operator. I am having trouble catching the std::flush manipulator.

First, a quick summary of what I do:

Given an object of LogClass, I want to do the following:

LogClass logger;
logger << "Some text" << std::flush;

... and catch the std::flush manipulator.

All input is sent directly to an internal string stream for later logging by the following inlined operator (which works fine):

class LogClass
{
    // ...

    std::ostringstream m_internalStream;

    template <typename T>
    LogClass & operator<<(const T & rhs)
    {
        m_internalStream << rhs;
        return *this;
    }

    // ...
};

I am trying to catch the std::flush manipulator by overloading as follows (which also works fine):

LogClass & LogClass::operator<<(std::ostream & (*manip)(std::ostream &))
{
    std::ostream & (* const flushFunc)(std::ostream &) = std::flush;

    // Is the supplied manipulator the same as std::flush?
    if ((manip == flushFunc)) {
        flush(); // <-- member function of LogClass
    } else {
        manip(m_stream);
    }

    return *this;
}

The problem shows if I try to make the local variable flushFunc static, as follows:

static std::ostream & (* const flushFunc)(std::ostream &) = std::flush;

In this case, the value of the incoming manip pointer is not equal to flushFunc.

Why is that? Does it have anything to do with template instantiations of the std::flush function for char?

I am using MS Visual Studio 2010 Pro.

The problem also shows in this small working code snippet:

#include <iostream>
#include <iomanip>

int main(int, char **)
{
    static std::ostream & (* const staticFlushPtr)(std::ostream &) = std::flush;
    std::ostream & (* const stackFlushPtr)(std::ostream &) = std::flush;

    std::cout << std::hex <<
            "staticFlushPtr: " << (void *) staticFlushPtr << "\n"
            "stackFlushPtr: " << (void *) stackFlushPtr << "\n";

    return 0;
}

... which gives this output on my machine:

staticFlushPtr: 013F1078
stackFlushPtr: 0FF10B30

Any ideas?

Best regards, Rein A. Apeland

Was it helpful?

Solution

This looks like a definite bug in the compiler. If there were DLLs or such involved, I could understand it, or at least make excuses, but in such a trivial example as your main... (g++ gets it right.)

About all I can suggest is that you insert a filtering streambuf in your output, which catches calls to sync.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top