drop in replacement for stringstream that compiles to nothing

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • jabbah
    New Member
    • Nov 2007
    • 63

    drop in replacement for stringstream that compiles to nothing

    hi

    I find myself using stringstream all over my code just to build debug messages that I may or may not write to cout later. that is very comfortable while developing but is generally useless for productive code.

    so I would like to have some construct that the compiler will remove in the case of NDEBUG. but I dont want to write #ifndef NDEBUG everywhere.

    I have tried with this, but seemingly the compiler still cant completely remove NullStream because if I raise the loopcount to something like 10e7 it takes 3 seconds (with MSVS 2005 /O2, even longer with cygwin/gcc344 or ubuntu7.1/gcc413 -O3)

    [code=c]
    #include <iostream>
    #include <string>
    #include <sstream>
    using namespace std;


    class NullStream
    {
    public:
    inline const NullStream& operator<< ( const string & s ) const
    {
    return *this;
    }
    inline const NullStream& operator<< ( int& i ) const
    {
    return *this;
    }
    inline const NullStream& operator<< ( unsigned int& i ) const
    {
    return *this;
    }
    };
    inline ostream& operator<<( ostream& o, const NullStream& n)
    {
    return o;
    }
    inline ostream& operator<<( ostream& o, const stringstream& s )
    {
    o << s.str();
    return o;
    }
    #ifdef NDEBUG
    typedef NullStream LogStream;
    #else
    typedef ostringstream LogStream;
    #endif




    void main_logstream( )
    {
    cout << __FUNCTION__ << "\n";
    LogStream buf;

    double clock_begin = clock();

    for ( unsigned int i = 0 ; i < 10e7 ; i++ )
    {
    buf << i << " ";
    }
    cout << "buffer: " << buf << "\n";
    cout << "time: " << ( ( clock() - clock_begin ) / CLOCKS_PER_SEC ) << " s\n";
    }
    [/code]


    I had expected that the compiler should be able to see that the body of that loop only consistst of a couple of calls to functions with empty bodies and thus the whole loop can be removed.

    Anybody any suggestions?
  • jabbah
    New Member
    • Nov 2007
    • 63

    #2
    uups, seemingly the compiler wont even remove

    [code=c]
    for ( unsigned int i = 0 ; i < 10e7 ; i++ )
    {
    (void)0;
    }
    [/code]

    am I asking for too much?

    CORRECTION: Sorry, that was wrong, for(...){ (void)0; } does get removed!

    Comment

    • jabbah
      New Member
      • Nov 2007
      • 63

      #3
      yet another correction: seemingly the (void)0; is removed but the (then empty) loop is not ... anyways ...

      back to my orignial question - just in case anybody cares - ive not managed to get something that can be #define'd to (void)0 that can be used like a stream but now I have a bunch of macros like

      [code=c]
      #define logstream2( stream, m1, m2 ) \
      if (true) { \
      ostream& log_stream = stream; \
      log_stream << m1 << m2; \
      } else (void)0
      [/code]
      (and also logstream1, logstream3, etc)

      This hasnt got the same interface as stream, ie operator<<(), but its the best I was able to achieve.

      Comment

      Working...