<p>I'd like to make a debug logging function with the same parameters as <code>printf</code>.  But one that can be removed by the pre-processor during optimized builds.</p>

<p>For example:</p>

<pre><code>Debug_Print("Warning: value %d &gt; 3!\n", value);
</code></pre>

<p>I've looked at variadic macros but those aren't available on all platforms. <code>gcc</code> supports them, <code>msvc</code> does not.</p>

[{'answer_id': 15248, 'author': 'Stu', 'author_id': 414, 'author_profile': 'https://Stackoverflow.com/users/414', 'pm_score': 1, 'selected': False, 'text': '<p>What platforms are they not available on? stdarg is part of the standard library:</p>\n\n<p><a href="http://www.opengroup.org/onlinepubs/009695399/basedefs/stdarg.h.html" rel="nofollow noreferrer">http://www.opengroup.org/onlinepubs/009695399/basedefs/stdarg.h.html</a></p>\n\n<p>Any platform not providing it is not a standard C implementation (or very, very old). For those, you will have to use varargs:</p>\n\n<p><a href="http://opengroup.org/onlinepubs/007908775/xsh/varargs.h.html" rel="nofollow noreferrer">http://opengroup.org/onlinepubs/007908775/xsh/varargs.h.html</a></p>\n'}, {'answer_id': 15262, 'author': 'Graeme Perrow', 'author_id': 1821, 'author_profile': 'https://Stackoverflow.com/users/1821', 'pm_score': 4, 'selected': False, 'text': '<p>Here\'s something that I do in C/C++. First off, you write a function that uses the varargs stuff (see the link in Stu\'s posting). Then do something like this:</p>\n\n<pre><code>\n int debug_printf( const char *fmt, ... );\n #if defined( DEBUG )\n  #define DEBUG_PRINTF(x) debug_printf x\n #else\n   #define DEBUG_PRINTF(x)\n #endif\n\n DEBUG_PRINTF(( "Format string that takes %s %s\\n", "any number", "of args" ));\n</code></pre>\n\n<p>All you have to remember is to use double-parens when calling the debug function, and the whole line will get removed in non-DEBUG code.</p>\n'}, {'answer_id': 15269, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 6, 'selected': True, 'text': "<p>I still do it the old way, by defining a macro (XTRACE, below) which correlates to either a no-op or a function call with a variable argument list. Internally, call vsnprintf so you can keep the printf syntax:</p>\n\n<pre><code>#include &lt;stdio.h&gt;\n\nvoid XTrace0(LPCTSTR lpszText)\n{\n   ::OutputDebugString(lpszText);\n}\n\nvoid XTrace(LPCTSTR lpszFormat, ...)\n{\n    va_list args;\n    va_start(args, lpszFormat);\n    int nBuf;\n    TCHAR szBuffer[512]; // get rid of this hard-coded buffer\n    nBuf = _vsnprintf(szBuffer, 511, lpszFormat, args);\n    ::OutputDebugString(szBuffer);\n    va_end(args);\n}\n</code></pre>\n\n<p>Then a typical #ifdef switch:</p>\n\n<pre><code>#ifdef _DEBUG\n#define XTRACE XTrace\n#else\n#define XTRACE\n#endif\n</code></pre>\n\n<p>Well that can be cleaned up quite a bit but it's the basic idea.</p>\n"}, {'answer_id': 15281, 'author': 'hyperlogic', 'author_id': 1841, 'author_profile': 'https://Stackoverflow.com/users/1841', 'pm_score': 3, 'selected': False, 'text': '<p>Ah, vsprintf() was the thing I was missing.  I can use this to pass the variable argument list directly to printf():</p>\n\n<pre><code>#include &lt;stdarg.h&gt;\n#include &lt;stdio.h&gt;\n\nvoid DBG_PrintImpl(char * format, ...)\n{\n    char buffer[256];\n    va_list args;\n    va_start(args, format);\n    vsprintf(buffer, format, args);\n    printf("%s", buffer);\n    va_end(args);\n}\n</code></pre>\n\n<p>Then wrap the whole thing in a macro.</p>\n'}, {'answer_id': 17029, 'author': 'Mat Noguchi', 'author_id': 1799, 'author_profile': 'https://Stackoverflow.com/users/1799', 'pm_score': 2, 'selected': False, 'text': '<p>Another fun way to stub out variadic functions is:</p>\n\n<pre><code>#define function sizeof\n</code></pre>\n'}, {'answer_id': 17932, 'author': 'Skizz', 'author_id': 1898, 'author_profile': 'https://Stackoverflow.com/users/1898', 'pm_score': 2, 'selected': False, 'text': '<p>In C++ you can use the streaming operator to simplify things:</p>\n\n<pre><code>#if defined _DEBUG\n\nclass Trace\n{\npublic:\n   static Trace &amp;GetTrace () { static Trace trace; return trace; }\n   Trace &amp;operator &lt;&lt; (int value) { /* output int */ return *this; }\n   Trace &amp;operator &lt;&lt; (short value) { /* output short */ return *this; }\n   Trace &amp;operator &lt;&lt; (Trace &amp;(*function)(Trace &amp;trace)) { return function (*this); }\n   static Trace &amp;Endl (Trace &amp;trace) { /* write newline and flush output */ return trace; }\n   // and so on\n};\n\n#define TRACE(message) Trace::GetTrace () &lt;&lt; message &lt;&lt; Trace::Endl\n\n#else\n#define TRACE(message)\n#endif\n</code></pre>\n\n<p>and use it like:</p>\n\n<pre><code>void Function (int param1, short param2)\n{\n   TRACE ("param1 = " &lt;&lt; param1 &lt;&lt; ", param2 = " &lt;&lt; param2);\n}\n</code></pre>\n\n<p>You can then implement customised trace output for classes in much the same way you would do it for outputting to <code>std::cout</code>.</p>\n'}, {'answer_id': 42775, 'author': 'David Bryson', 'author_id': 3663, 'author_profile': 'https://Stackoverflow.com/users/3663', 'pm_score': 1, 'selected': False, 'text': '<p>Part of the problem with this kind of functionality is that often it requires\nvariadic macros.  These were standardized fairly recently(C99), and lots of\nold C compilers do not support the standard, or have their own special work\naround.</p>\n\n<p>Below is a debug header I wrote that has several cool features:</p>\n\n<ul>\n<li>Supports C99 and C89 syntax for debug macros</li>\n<li>Enable/Disable output based on function argument</li>\n<li>Output to file descriptor(file io)</li>\n</ul>\n\n<p>Note: For some reason I had some slight code formatting problems.</p>\n\n<pre><code>#ifndef _DEBUG_H_\n#define _DEBUG_H_\n#if HAVE_CONFIG_H\n#include "config.h"\n#endif\n\n#include "stdarg.h"\n#include "stdio.h"\n\n#define ENABLE 1\n#define DISABLE 0\n\nextern FILE* debug_fd;\n\nint debug_file_init(char *file);\nint debug_file_close(void);\n\n#if HAVE_C99\n#define PRINT(x, format, ...) \\\nif ( x ) { \\\nif ( debug_fd != NULL ) { \\\nfprintf(debug_fd, format, ##__VA_ARGS__); \\\n} \\\nelse { \\\nfprintf(stdout, format, ##__VA_ARGS__); \\\n} \\\n}\n#else\nvoid PRINT(int enable, char *fmt, ...);\n#endif\n\n#if _DEBUG\n#if HAVE_C99\n#define DEBUG(x, format, ...) \\\nif ( x ) { \\\nif ( debug_fd != NULL ) { \\\nfprintf(debug_fd, "%s : %d " format, __FILE__, __LINE__, ##__VA_ARGS__); \\\n} \\\nelse { \\\nfprintf(stderr, "%s : %d " format, __FILE__, __LINE__, ##__VA_ARGS__); \\\n} \\\n}\n\n#define DEBUGPRINT(x, format, ...) \\\nif ( x ) { \\\nif ( debug_fd != NULL ) { \\\nfprintf(debug_fd, format, ##__VA_ARGS__); \\\n} \\\nelse { \\\nfprintf(stderr, format, ##__VA_ARGS__); \\\n} \\\n}\n#else /* HAVE_C99 */\n\nvoid DEBUG(int enable, char *fmt, ...);\nvoid DEBUGPRINT(int enable, char *fmt, ...);\n\n#endif /* HAVE_C99 */\n#else /* _DEBUG */\n#define DEBUG(x, format, ...)\n#define DEBUGPRINT(x, format, ...)\n#endif /* _DEBUG */\n\n#endif /* _DEBUG_H_ */\n</code></pre>\n'}, {'answer_id': 55663, 'author': 'Ferruccio', 'author_id': 4086, 'author_profile': 'https://Stackoverflow.com/users/4086', 'pm_score': 2, 'selected': False, 'text': '<p>@CodingTheWheel:</p>\n\n<p>There is one slight problem with your approach. Consider a call such as</p>\n\n<pre><code>XTRACE("x=%d", x);\n</code></pre>\n\n<p>This works fine in the debug build, but in the release build it will expand to:</p>\n\n<pre><code>("x=%d", x);\n</code></pre>\n\n<p>Which is perfectly legitimate C and will compile and usually run without side-effects but generates unnecessary code. The approach I usually use to eliminate that problem is:</p>\n\n<ol>\n<li><p>Make the XTrace function return an int (just return 0, the return value doesn\'t matter)</p></li>\n<li><p>Change the #define in the #else clause to:</p>\n\n<pre><code>0 &amp;&amp; XTrace\n</code></pre></li>\n</ol>\n\n<p>Now the release version will expand to:</p>\n\n<pre><code>0 &amp;&amp; XTrace("x=%d", x);\n</code></pre>\n\n<p>and any decent optimizer will throw away the whole thing since short-circuit evaluation would have prevented anything after the &amp;&amp; from ever being executed.</p>\n\n<p>Of course, just as I wrote that last sentence, I realized that perhaps the original form might be optimized away too and in the case of side effects, such as function calls passed  as parameters to XTrace, it might be a better solution since it will make sure that debug and release versions will behave the same.</p>\n'}, {'answer_id': 67428, 'author': 'snstrand', 'author_id': 10089, 'author_profile': 'https://Stackoverflow.com/users/10089', 'pm_score': 5, 'selected': False, 'text': '<p>This is how I do debug print outs in C++. Define \'dout\' (debug out) like this:</p>\n\n<pre><code>#ifdef DEBUG\n#define dout cout\n#else\n#define dout 0 &amp;&amp; cout\n#endif\n</code></pre>\n\n<p>In the code I use \'dout\' just like \'cout\'.</p>\n\n<pre><code>dout &lt;&lt; "in foobar with x= " &lt;&lt; x &lt;&lt; " and y= " &lt;&lt; y &lt;&lt; \'\\n\';\n</code></pre>\n\n<p>If the preprocessor replaces \'dout\' with \'0 &amp;&amp; cout\' note that &lt;&lt; has higher precedence than &amp;&amp; and short-circuit evaluation of &amp;&amp; makes the whole line evaluate to 0. Since the 0 is not used the compiler generates no code at all for that line.</p>\n'}, {'answer_id': 689659, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 1, 'selected': False, 'text': '<p>Have a look at this thread:</p>\n\n<ul>\n<li><a href="https://stackoverflow.com/questions/679979/">How to make a variadic macro (variable number of arguments)</a></li>\n</ul>\n\n<p>It should answer your question.</p>\n'}, {'answer_id': 13020140, 'author': 'Koffiman', 'author_id': 914689, 'author_profile': 'https://Stackoverflow.com/users/914689', 'pm_score': 0, 'selected': False, 'text': '<p>Having come across the problem today, my solution is the following macro:</p>\n<pre><code>    static TCHAR __DEBUG_BUF[1024];\n    #define DLog(fmt, ...)  swprintf(__DEBUG_BUF, fmt, ##__VA_ARGS__); OutputDebugString(__DEBUG_BUF) \n  \n</code></pre>\n<p>You can then call the function like this:</p>\n<pre><code>    int value = 42;\n    DLog(L&quot;The answer is: %d\\n&quot;, value);\n</code></pre>\n'}, {'answer_id': 18129398, 'author': 'mousomer', 'author_id': 281617, 'author_profile': 'https://Stackoverflow.com/users/281617', 'pm_score': 0, 'selected': False, 'text': '<p>This is what I use:</p>\n\n<pre><code>inline void DPRINTF(int level, char *format, ...)\n{\n#    ifdef _DEBUG_LOG\n        va_list args;\n        va_start(args, format);\n        if(debugPrint &amp; level) {\n                vfprintf(stdout, format, args);\n        }\n        va_end(args);\n#    endif /* _DEBUG_LOG */\n}\n</code></pre>\n\n<p>which costs absolutely nothing at run-time when the _DEBUG_LOG flag is turned off.</p>\n'}, {'answer_id': 39186784, 'author': 'Orwellophile', 'author_id': 912236, 'author_profile': 'https://Stackoverflow.com/users/912236', 'pm_score': 0, 'selected': False, 'text': '<p>This is a TCHAR version of user\'s answer, so it will work as ASCII (<em>normal</em>), or Unicode mode (more or less).</p>\n\n<pre><code>#define DEBUG_OUT( fmt, ...) DEBUG_OUT_TCHAR(       \\\n            TEXT(##fmt), ##__VA_ARGS__ )\n#define DEBUG_OUT_TCHAR( fmt, ...)                  \\\n            Trace( TEXT("[DEBUG]") #fmt,            \\\n            ##__VA_ARGS__ )\nvoid Trace(LPCTSTR format, ...)\n{\n    LPTSTR OutputBuf;\n    OutputBuf = (LPTSTR)LocalAlloc(LMEM_ZEROINIT,   \\\n            (size_t)(4096 * sizeof(TCHAR)));\n    va_list args;\n    va_start(args, format);\n    int nBuf;\n    _vstprintf_s(OutputBuf, 4095, format, args);\n    ::OutputDebugString(OutputBuf);\n    va_end(args);\n    LocalFree(OutputBuf); // tyvm @sam shaw\n}\n</code></pre>\n\n<p><em>I say, "more or less", because it won\'t automatically convert ASCII string arguments to WCHAR, but it should get you out of most Unicode scrapes without having to worry about wrapping the format string in TEXT() or preceding it with L.</em></p>\n\n<p>Largely derived from <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms680582(v=vs.85).aspx" rel="nofollow">MSDN: Retrieving the Last-Error Code</a></p>\n'}, {'answer_id': 63047805, 'author': 'parth_07', 'author_id': 3447475, 'author_profile': 'https://Stackoverflow.com/users/3447475', 'pm_score': 0, 'selected': False, 'text': "<p>Not exactly what's asked in the question . But this code will be helpful for debugging purposes , it will print each variable's value along with it's name . This is completely type independent and supports variable number of arguments.\nAnd can even display values of STL's nicely , given that you overload output operator for them</p>\n<pre><code>#define show(args...) describe(#args,args);\ntemplate&lt;typename T&gt;\nvoid describe(string var_name,T value)\n{\n    clog&lt;&lt;var_name&lt;&lt;&quot; = &quot;&lt;&lt;value&lt;&lt;&quot; &quot;;\n}\n\ntemplate&lt;typename T,typename... Args&gt;\nvoid describe(string var_names,T value,Args... args)\n{\n    string::size_type pos = var_names.find(',');\n    string name = var_names.substr(0,pos);\n    var_names = var_names.substr(pos+1);\n    clog&lt;&lt;name&lt;&lt;&quot; = &quot;&lt;&lt;value&lt;&lt;&quot; | &quot;;\n    describe(var_names,args...);\n}\n</code></pre>\n<p>Sample Use :</p>\n<pre><code>int main()\n{\n    string a;\n    int b;\n    double c;\n    a=&quot;string here&quot;;\n    b = 7;\n    c= 3.14;\n    show(a,b,c);\n}\n</code></pre>\n<p>Output :</p>\n<pre><code>a = string here | b = 7 | c = 3.14 \n</code></pre>\n"}]
['https://Stackoverflow.com/questions/15240', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1841/']