Noticing this thread, I thought it would be interesting to start one on C++ techniques. Maybe a mod could make it a sticky, as well?
Here's the first installment: debugging macros. Very handy when you just want to see the name and value of a variable or expression. For convenience, they can be turned off by defining NDEBUG.
Example usage:Code:#ifndef BUG_HPP #define BUG_HPP /* A simple set of macros for printing variable/expression text and values. SBUG( stream, expression ) writes output to any std::ostream-like object. BUG( expression ) writes output to std::cout. If NDEBUG is defined, macros expand to nothing. */ #include <ostream> // for std::cout #include <cctype> // for isdigit namespace BUG_IMPL_ { template < typename Stream, typename Type > void print_dispatch( Stream& stream, char const* expression, Type const& value ) { stream << "*** [" << __FILE__ << ", line #" << __LINE__ << "] ***\n"; /* We'll flush the stream twice, just in case the outputting of 'value' should crash, throw an exception, etc - at least we'll know what file/line we were at before the fact */ stream.flush( ); /* Check if the expression was some sort of literal */ int ch = expression[ 0 ]; if( !isalpha( ch ) && ch != '_' ) { /* If already quoted, output as is */ if( ch == '"' || ch == '\'' ) stream << " " << expression << "\n"; else stream << " '" << expression << "'\n"; } else stream << " " << expression << " = '" << value << "'\n"; stream.flush( ); } } // namespace BUG_IMPL_ #ifndef NDEBUG #define SBUG( stream, expression ) BUG_IMPL_::print_dispatch( stream, #expression, expression ); #define BUG( expression ) SBUG( std::cout, expression ) #else #define SBUG( stream, expression ) #define BUG( expression ) #endif // !NDEBUG #endif // BUG_HPP
Output:Code:#include <iostream> #include <cmath> int main( void ) { BUG( "entering main" ); int a = 200; float b = 0.5; char const* c = "ten"; BUG( a ); BUG( b ); BUG( sqrt( a * b ) ); BUG( c ); BUG( "exiting main" ); }
And don't forget, they work with user-defined types, too:*** [test.cpp, line #62] ***
"entering main"
*** [test.cpp, line #69] ***
a = '200'
*** [test.cpp, line #70] ***
b = '0.5'
*** [test.cpp, line #71] ***
sqrt( a * b ) = '10'
*** [test.cpp, line #72] ***
c = 'ten'
*** [test.cpp, line #73] ***
"exiting main"
Output:Code:#include <ostream> #include <string> using namespace std; struct name { name( string const& first, string const& last ) : first( first ), last( last ) { } friend ostream& operator << ( ostream& stream, name const& name ) { return stream << name.last << ", " << name.first; } string first, last; }; int main( void ) { name someone( "Sebastian", "Garth" ); BUG( someone ); }
Cheers!*** [test.cpp, line #103] ***
someone = 'Garth, Sebastian'



LinkBack URL
About LinkBacks



