CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6

Thread: macro tricks

  1. #1
    Join Date
    Jul 2007
    Location
    london
    Posts
    247

    macro tricks

    i was wondering if it was possible to do this?

    Code:
    #define print_code(line) line cout << quote line quote << endl;
    #define quote "
    
    print_code(true;)
    to be macroed to

    Code:
    true; cout << "true;" << endl;
    how could i do this? just curiouse

    thanks

    UPDATE SOLVED

    Code:
    #define print_code(line) line cout << #line << endl;
    Last edited by g3RC4n; March 11th, 2008 at 07:41 PM.

  2. #2
    Join Date
    Nov 2006
    Location
    Essen, Germany
    Posts
    1,344

    Re: macro tricks

    That´s funny, yesterday I was looking for some debug helper macros because my compiler offers none and I really miss Microsoft´s debug macros. I found two interesting articles, combined them, and came up with this solution. It automatically detects the file and line number, prepends them to the message and prints the message in my debug console. Modifications may be necessary for different compilers, mine catches debugger messages yield by OutputDebugString and prints them in a separate console.

    Code:
    #ifndef VCLTraceH
    #define VCLTraceH
    
    #ifdef NDEBUG
    #define TRACE (void)0
    #else
    #define TRACE VCLTrace(__FILE__,__LINE__)
    
    class VCLTrace
    {
       std::string     File;
       unsigned int  Line;
    
    public:
       VCLTrace( const char* pszFile, unsigned int uiLine ) :
          File( pszFile ),
          Line( uiLine )
       {
       }
    
       template<typename T1>
       void operator()( const T1& op1 )
       {
          std::ostringstream os;
          os << op1;
          trace( os.str() );
       }
    
       template<
       typename T1, typename T2>
       void operator()( const T1& op1, const T2& op2 )
       {
          std::ostringstream os;
          os << op1 << op2;
          trace( os.str() );
       }
    
    
       template<
       typename T1, typename T2, typename T3>
       void operator()( const T1& op1, const T2& op2, const T3& op3 )
       {
          std::ostringstream os;
          os << op1 << op2 << op3;
          trace( os.str() );
       }
    
       template<
       typename T1, typename T2, typename T3, typename T4>
       void operator()( const T1& op1, const T2& op2, const T3& op3, const T4& op4 )
       {
          std::ostringstream os;
          os << op1 << op2 << op3 << op4;
          trace( os.str() );
       }
    
       template<
       typename T1, typename T2, typename T3, typename T4, typename T5>
       void operator()( const T1& op1, const T2& op2, const T3& op3, const T4& op4, const T5& op5 )
       {
          std::ostringstream os;
          os << op1 << op2 << op3 << op4 << op5;
          trace( os.str() );
       }
    
    private:
       void trace( const std::string& strMessage )
       {
          std::ostringstream os;
          os << File << "(" << Line << "): " << strMessage;
          OutputDebugString( os.str().c_str() );
       }
    };
    #endif
    Macro usage:

    Code:
    int main()
    {
       int a = 10;
       double b = 3.5;
       TRACE( "Welcome to the show, int a=", a, " and double b=", b );
    }
    - Guido

  3. #3
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: macro tricks

    That's a very good idea!
    A neat demostration of using templates too.

    (I'd rate your post but the system won't let me until I rate someone else first)

  4. #4
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,158

    Re: macro tricks

    the disadvantage is that you limit yourself to a max of 4 different parameters.
    In my opinion, a set of embracing macros such as
    TRACE << "all of tracing done here via operator<<" << TRACE_END
    would be much better.
    I use that in all of my code.
    something like this:
    Code:
          #define TRACE_BASE(pp_tracer, pp_traceMode) \
             try \
             { \
                if(pp_tracer.isTracing(pp_traceMode)) \
                { \
                   Tracer& xx_tracer = pp_tracer; \
                   TraceMode xx_traceMode = pp_traceMode; \
                   std::ostringstream xx_os_yy_1234;
    
          #define TRACE_END \
                   std::endl; \
                   xx_tracer.trace( __FILE__, __LINE__, xx_traceMode, xx_os_yy_1234 ); \
                } \
             } \
             catch(...) {}
    I must admit that I don't have a snippet ready to demonstrate the use of these macros, but they may give a notion of what is done ...

    What I really hate is a set of macros that limits the user to a certain (arbitrary) value of trace "parameters".
    Last edited by Richard.J; March 12th, 2008 at 03:55 PM.

  5. #5
    Join Date
    Nov 2006
    Location
    Essen, Germany
    Posts
    1,344

    Re: macro tricks

    Quote Originally Posted by Richard.J
    the disadvantage is that you limit yourself to a max of 4 different parameters.
    In my opinion, a set of embracing macros such as
    TRACE << "all of tracing done here via operator<<" << TRACE_END
    would be much better.
    I use that in all of my code.
    something like this:
    Code:
          #define TRACE_BASE(pp_tracer, pp_traceMode) \
             try \
             { \
                if(pp_tracer.isTracing(pp_traceMode)) \
                { \
                   Tracer& xx_tracer = pp_tracer; \
                   TraceMode xx_traceMode = pp_traceMode; \
                   std::ostringstream xx_os_yy_1234;
    
          #define TRACE_END \
                   std::endl; \
                   xx_tracer.trace( __FILE__, __LINE__, xx_traceMode, xx_os_yy_1234 ); \
                } \
             } \
             catch(...) {}
    I must admit that I don't have a snippet ready to demonstrate the use of these macros, but they may give a notion of what is done ...

    What I really hate is a set of macros that limits the user to a certain (arbitrary) value of trace "parameters".
    Touchee... updated my macro to handle any number of parameters. Interestingly the resulting code is smaller than the one handling 4 parameters

    Code:
    #include <string>
    #include <sstream>
    #include <iostream>
    
    #ifdef NDEBUG
    #define TRACE VCLTrace(__FILE__,__LINE__),
    #else
    #define TRACE (void)0,
    #endif
    
    struct VCLTraceItem
    {
       std::string m_strItem;
    
       template<typename T>
       VCLTraceItem( const T& op )
       {
          std::ostringstream oss;
          oss << op;
          m_strItem = oss.str();
       }
    };
    
    class VCLTrace
    {
       std::string m_strTraceLine;
    public:
       VCLTrace( const char* pszFile, unsigned int uiLine )
       {
          std::ostringstream oss;
          oss << pszFile << " (" << uiLine << ") :";
          m_strTraceLine = oss.str();
       }
    
       ~VCLTrace()
       {
          OutputDebugString( m_strTraceLine.c_str() );
       }
    
       VCLTrace& operator,( const VCLTraceItem& op )
       {
          m_strTraceLine += op.m_strItem;
          return *this;
       }
    };
    
    int main()
    {
       int a = 10;
       double d = 3.5;
       bool b = true;
       std::string s = "STRING";
    
       TRACE "This is a test, a=", a, ", b=", b, ", s= ", s, ", d=", d;
    }
    Last edited by GNiewerth; March 13th, 2008 at 05:41 AM.
    - Guido

  6. #6
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: macro tricks

    Just wanted to write that C++ 0x will add variadic arguments to templates. Thus in the future there will be a way to write this cleaner. Something like:
    Code:
    class Trace
    {
    public:
      template<typename... Args>
      Trace(const char* file, unsigned int line, Args... args) {
        s << file << '(' << line << "):";
        trace(args);
        std::cout << s;
      }
    private:
      ostringstream s;
      
      template<typename T, typename... Args>
      void trace(T value, Args... args) {
        s << value;
        trace(args);
      }
    
      void trace() {};
    }
    
    #define TRACE(...) Trace(__FILE__, __LINE__, __VA_ARGS__)
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured