「引数で与えられた書式+引数を、ソースファイル名と行番号付きで表示するマクロ」の作り方4種。
printf といっても出力先はデバッガの出力ウィンドウです
(_CrtDbgReport
使ってるので _CrtSetReportMode/_CrtSetReportFile
で出力先を標準出力とかに変えられます)。
その1. __noop
を使う
関数オブジェクトのコンストラクタで __FILE__
と __LINE__
を受け取り、括弧演算子で printf
な書式と引数を受け付けます。
リリースビルドでは __noop
で TRACE_F
マクロの中身が実行されないようにします。
#ifdef _DEBUG
#include <crtdbg.h>
#define TRACE_F debug_trace_format(__FILE__, __LINE__)
class debug_trace_format
{
private:
const char* _file;
long _line;
public:
debug_trace_format(const char* file, long line) : _file(file), _line(line) {}
void operator ()(const char *fmt, ...)
{
va_list arg;
va_start(arg, fmt);
int size = vsnprintf(NULL, 0, fmt, arg);
std::unique_ptr<char[]> buf(new char[size + 1]);
vsnprintf(buf.get(), size + 1, fmt, arg);
_CrtDbgReport(_CRT_WARN, _file, _line, NULL, "%s", buf.get());
va_end(arg);
}
};
#else
#define TRACE_F __noop
#endif
int main()
{
//_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
//_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
TRACE_F("%s: %d\n", "errcode", 1234);
return 0;
}
その2. __VA_ARGS__
を使う
いつからか Visual C++ で __VA_ARGS__
が使えるようになっていました。
#ifdef _DEBUG
#include <crtdbg.h>
#define TRACE_F(fmt, ...) _CrtDbgReport(_CRT_WARN, __FILE__, __LINE__, NULL, fmt, __VA_ARGS__);
#else
#define TRACE_F(fmt, ...)
#endif
int main()
{
//_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
//_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
TRACE_F("%s: %d\n", "errcode", 1234);
return 0;
}
楽ちんです。
その3. stringstream
を使う
可変個引数が気持ち悪い人のために stringstream
を使う版。
#include <sstream>
#ifdef _DEBUG
#include <crtdbg.h>
#define TRACE_F(expr) _CrtDbgReport(_CRT_WARN, __FILE__, __LINE__, NULL, "%s", \
static_cast<::std::ostringstream&>(::std::ostringstream() << expr).str().c_str() )
#else
#define TRACE_F(expr)
#endif
int main()
{
//_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
//_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
TRACE_F("errcode: " << 1234 << std::endl);
return 0;
}
その4. boost/format
を使う
boost が使えるなら boost/format で。
#include <boost/format.hpp>
#ifdef _DEBUG
#include <crtdbg.h>
#define TRACE_F(fmt, expr) _CrtDbgReport(_CRT_WARN, __FILE__, __LINE__, NULL, "%s", \
(::boost::format(fmt) % expr).str().c_str() )
#else
#define TRACE_F(fmt, expr)
#endif
int main()
{
//_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
//_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
TRACE_F("%s: %d\n", "errcode" % 1234);
return 0;
}
その?. ATLTRACE
を使う
ファイル名と行番号を表示させる方法がわからなかったので使っていない。