I've a problem , as the following code discribe itself.
1 #include<stdlib.h>
2 #include<stdio.h>
3 void log()
4 {
5 printf("Log [Line:%d]\n",__LINE__);
6 }
7 int main()
8 {
9 log();
10 log();
11 }
The expected result is
Log [Line:9]
Log [Line:10]
But, the fact is
Log [Line:5]
Log [Line:5]
No surprising, LINE has been substituted at the pre-process stage as 5.
My Question is, how to design the log function to get the expected result?
Thanks!
You need to write a macro:
#define LOG printf("Log [Line:%d]\n",__LINE__)
then use it:
int main() {
LOG;
LOG;
}
This works because the macro is expanded at its point of use, giving the __LINE__ macro the correct value.
A macro can overcome this, by passing in the __LINE__ as a parameter to the invoked function.
Another, perhaps complementary approach is to pass some context to the function as a parameter, with a default value that says 'use the line number'. This is illustrated by this code snippet which is doing error handling with the pattern:
int read_byte(FILE* f,int line=0) {
int ret = fgetc(f);
if(-1 == ret)
throw (line? line: __LINE__);
return ret;
}
int read_uint16(FILE* f,int line=0) {
int hi = read_byte(f,(line? line: __LINE__));
int lo = read_byte(f,(line? line: __LINE__));
return (hi<<8)|lo;
}
int main() {
...
try {
int i = read_uint16(f,__LINE__);
} catch(int line) {
fprintf(stderr,"Error at line %d\n",line);
}
...
}
Finally, this all smacks of wanting to get a stack trace out of C/C++ code (especially in the error handling cases). Look at VALGRIND_PRINTF_BACKTRACE(format, ...)
You can modify your existing function slightly, and wrap it in a macro:
#include<stdlib.h>
#include<stdio.h>
#define log() real_log(__LINE__)
void real_log(int line)
{
printf("Log [Line:%d]\n", line);
}
int main()
{
log();
log();
}
Related
I have a single cpp file of about 100 lines with the following contents.
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/FrontendActions.h>
#include <iostream>
// The filename that will be processed (twice).
static const char* FILENAME = "simple.cpp";
// System header locations, you may need to
// adjust these.
static const char* SYSTEM_HEADERS[] =
{
"/usr/include/c++/5.4.0",
"/usr/include/x86_64-linux-gnu/c++/5.4.0",
"/usr/include/c++/5.4.0/backward",
"/usr/local/lib/clang/4.0.0/include",
"/usr/include/x86_64-linux-gnu",
"/usr/include"
};
// Location for builtin headers. You may need to
// adjust this.
static const char* RESOURCE_DIR = "/usr/local/lib/clang/4.0.0";
// Uncomment this to see header search paths.
// #define PRINT_HEADER_SEARCH_PATHS
// Constructs a CompilerInvocation
// that must be fed to a CompilerInstance.
clang::CompilerInvocation* makeInvocation();
// Executes a single SyntaxOnlyAction on
// the given CompilerInstance.
void secondCallThisFunctionFails(clang::CompilerInstance& instance);
int main()
{
using namespace clang;
CompilerInstance instance;
instance.createDiagnostics();
instance.setInvocation(makeInvocation());
instance.getFrontendOpts().Inputs.emplace_back
(
FILENAME,
FrontendOptions::getInputKindForExtension(FILENAME)
);
// First call is OK.
secondCallThisFunctionFails(instance);
// Second call results in assertion failures.
secondCallThisFunctionFails(instance);
return 0;
}
clang::CompilerInvocation* makeInvocation()
{
using namespace clang;
auto invocation = new CompilerInvocation();
invocation->TargetOpts->Triple = llvm::sys::getDefaultTargetTriple();
invocation->setLangDefaults(
*invocation->getLangOpts(),
IK_CXX,
llvm::Triple(invocation->TargetOpts->Triple),
invocation->getPreprocessorOpts(),
LangStandard::lang_cxx11);
auto& headerSearchOpts = invocation->getHeaderSearchOpts();
#ifdef PRINT_HEADER_SEARCH_PATHS
headerSearchOpts.Verbose = true;
#else
headerSearchOpts.Verbose = false;
#endif
headerSearchOpts.UseBuiltinIncludes = true;
headerSearchOpts.UseStandardSystemIncludes = true;
headerSearchOpts.UseStandardCXXIncludes = true;
headerSearchOpts.ResourceDir = RESOURCE_DIR;
for (const auto sytemHeader : SYSTEM_HEADERS)
{
headerSearchOpts.AddPath(sytemHeader, frontend::System, false, false);
}
return invocation;
}
void secondCallThisFunctionFails(clang::CompilerInstance& instance)
{
using namespace clang;
SyntaxOnlyAction action;
if (instance.ExecuteAction(action))
{
std::cout << "Action succeeded.\n";
}
else
{
std::cout << "Action failed.\n";
}
}
As you can see, the main function is quite simple, and calls a function twice at the end. The second time this function is called I get an assertion failure, which surprises me.
The contents of the file simple.cpp is
// test wether we actually configured C++11 or greater
#include <thread>
int main() { return 0; }
The output of this program on my machine is:
Action succeeded.
clangapitest: ../tools/clang/lib/Basic/SourceManager.cpp:819: clang::FileID clang::SourceManager::getFileIDLoaded(unsigned int) const: Assertion `0 && "Invalid SLocOffset or bad function choice"' failed.
Aborted (core dumped)
The problem is: I want to execute more than one action on a CompilerInstance. What state do I have to reset in order to not get assertion failures?
To build it yourself you have to link with some static clang and llvm libraries. Here's the CMakeLists.txt file if interested:
add_clang_executable(clangapitest clangapitest.cpp)
target_link_libraries(clangapitest clangFrontend)
I made a new directory path/to/llvm/tools/clang/tools/clangapitest and adjusted the CMakeLists.txt file in path/to/llvm/tools/clang/tools/CMakeLists.txt to have an extra line add_subdirectory(clangapitest).
Well, I figured it out. In the doxygen documentation of CompilerInstance::ExecuteAction, it states that an invocation object and diagnostics object should have been initialized, and no other state (hence no source nor filemanager). So the following works:
SyntaxOnlyAction action;
instance.setSourceManager(nullptr);
instance.createDiagnostics();
if (instance.ExecuteAction(action))
{
std::cout << "Action succeeded.\n";
}
else
{
std::cout << "Action failed.\n";
}
I'm wondering how I you can create and register a function from the C++-side that returns a table when called from the Lua-side.
I've tried a lot of things but nothing did really work. :/
(sorry for the long code)
This for example won't work, because Register() expects a "luaCFunction"-styled function:
LuaPlus::LuaObject Test( LuaPlus::LuaState* state ) {
int top = state->GetTop();
std::string var( state->ToString(1) );
LuaPlus::LuaObject tableObj(state);
tableObj.AssignNewTable(state);
if (var == "aaa")
tableObj.SetString("x", "ABC");
else if (var == "bbb")
tableObj.SetString("x", "DEF");
tableObj.SetString("y", "XYZ");
return tableObj;
}
int main()
{
LuaPlus::LuaState* L = LuaPlus::LuaState::Create(true);
//without true I can't access the standard libraries like "math.","string."...
//with true, GetLastError returns 2 though (ERROR_FILE_NOT_FOUND)
//no side effects noticed though
LuaPlus::LuaObject globals = L->GetGlobals();
globals.Register("Test",Test);
char pPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH,pPath);
strcat_s(pPath,MAX_PATH,"\\test.lua");
if(L->DoFile(pPath)) {
if( L->GetTop() == 1 ) // An error occured
std::cout << "An error occured: " << L->CheckString(1) << std::endl;
}
}
When I try to set it up as a luaCFunction-function it just crashes (0x3) and says:
Assertion failed: 0, file C:\......\luafunction.h, line 41
int Test( LuaPlus::LuaState* state ) {
int top = state->GetTop();
std::string var( state->ToString(1) );
LuaPlus::LuaObject tableObj(state);
tableObj.AssignNewTable(state);
if (var == "aaa")
tableObj.SetString("x", "ABC");
else if (var == "bbb")
tableObj.SetString("x", "DEF");
tableObj.SetString("y", "XYZ");
tableObj.Push();
return state->GetTop() - top;
}
For clarification: from the Lua side I wanted it to be callable like:
myVar = Test("aaa")
Print(myVar) -- output: ABC
EDIT: The Print function comes from here. And was basically the cause for this to not work. Print can only print strings not tables... The C++ code from above works fine if you just return 1.
This is the documentation that came with my LuaPlus version btw: http://luaplus.funpic.de/
I really hope you can help me.. I'm already starting to think that it is not possible. :'(
edit:
I totally forgot to say that using PushStack() lead into an error because "the member does not exist"...
After some painstaking probing from the long comment discussion, I'm posting this answer to help summary the situation and hopefully to offer some useful advice.
The main issue the OP was running into was that the wrong print function was being called in the lua test script. Contrary to the original code shown the real code the OP was testing against was calling Print(myVar) which is a custom provided lua_CFunction and not the builtin print function.
Somehow along the way, this ended up creating some instantiation of template <typename RT> class LuaFunction and calling the overloaded operator()(). From inspecting the luafunction.h from luaPlus any lua errors that occurs inside this call will get swallowed up without any kind of logging (not a good design decision on luaPlus's part):
if (lua_pcall(L, 0, 1, 0)) {
const char* errorString = lua_tostring(L, -1); (void)errorString;
luaplus_assert(0);
}
To help catch future errors like this, I suggest adding a new luaplus_assertlog macro. Specifically, this macro will include the errorString so that the context isn't completely lost and hopefully help with debugging. This change hopefully won't break existing uses of luaplua_assert from other parts of the API. In the long run though, it's probably better to modify luaplus_assert so it actually includes something meaningful.
Anyway here's a diff of the changes made:
LuaPlusInternal.h
## -81,5 +81,6 ##
} // namespace LuaPlus
#if !LUAPLUS_EXCEPTIONS
+#include <stdio.h>
#include <assert.h>
#define luaplus_assert(e) if (!(e)) assert(0)
## -84,5 +85,6 ##
#include <assert.h>
#define luaplus_assert(e) if (!(e)) assert(0)
+#define luaplus_assertlog(e, msg) if (!(e)) { fprintf(stderr, msg); assert(0); }
//(void)0
#define luaplus_throw(e) assert(0)
//(void)0
LuaFunction.h
## -21,7 +21,7 ##
class LuaFunction
{
public:
- LuaFunction(LuaObject& _functionObj)
+ LuaFunction(const LuaObject& _functionObj)
: functionObj(_functionObj) {
}
## -36,7 +36,7 ##
if (lua_pcall(L, 0, 1, 0)) {
const char* errorString = lua_tostring(L, -1); (void)errorString;
- luaplus_assert(0);
+ luaplus_assertlog(0, errorString);
}
return LPCD::Type<RT>::Get(L, -1);
}
In the change above, I opted not to use std::cerr simply because C++ streams tend to be heavier than plain-old C-style io functions. This is especially true if you're using mingw as your toolchain -- the ld linker is unable to eliminate unused C++ stream symbols even if your program never uses it.
With that in place, here's an example where an unprotected call is made to a lua function so you can see the errorString printed out prior to the crash:
// snip...
int main(int argc, const char *argv[])
{
LuaStateAuto L ( LuaState::Create(true) );
LuaObject globals = L->GetGlobals();
globals.Register("Test", Test);
globals.Register("Print", Print);
if(argc > 1)
{
/*
if (L->DoFile(argv[argc - 1]))
std::cout << L->CheckString(1) << '\n';
/*/
L->LoadFile( argv[argc - 1] );
LuaFunction<int> f ( LuaObject (L, -1) );
f();
//*/
}
}
Running the above will trigger the crash but will include a semi-helpful error message:
g++ -Wall -pedantic -O0 -g -I ./Src -I ./Src/LuaPlus/lua51-luaplus/src plustest.cpp -o plustest.exe lua51-luaplus.dll
plustest.exe plustest.lua
plustest.lua:2: bad argument #1 to 'Print' (string expected, got table)Assertion failed!
Program: G:\OSS\luaplus51-all\plustest.exe
File: ./Src/LuaPlus/LuaFunction.h, Line 39
Expression: 0
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
first you may try to register the function using RegisterDirect(), this may avoid lua_CFunction's problem, check the luaplus manual.like this
LuaPlus::LuaObject globals = L->GetGlobals();
globals.RegisterDirect("Test",Test);
second if I remeber to create a table have two solutions,like this
//first
LuaObject globalsObj = state->GetGlobals();
LuaObject myArrayOfStuffTableObj = globalsObj.CreateTable("MyArrayOfStuff");
//second
LuaObject aStandaloneTableObj;
aStandaloneTableObj.AssignNewTable(state);
check whether you have use the right function.
third I remember the lua stack object is not the luaobject, they have a conversion, may be you can try this
LuaStackObject stack1Obj(state, 1);
LuaObject nonStack1Obj = stack1Obj;
forth, like the function Test() you have give above, the table tableObj you have pushing onto the lua stack, you must remember to clear the object.
#include <iostream>
void LOG_TRACE() { std::cout << "reach here"; }
#define LOG_LL_TRACE LOG_TRACE
#define LL_TRACE 0
#define __LOG(level) LOG_##level()
#define LOG(level) __LOG(##level)
int main()
{
LOG(LL_TRACE);
return 0;
}
The code is worked under Visual Studio, but report: test.cpp:13:1: error: pasting "(" and "LL_TRACE" does not give a valid preprocessing token.
How can I fix it?
ps: The macro expansion is supposed to be LOG(LL_TRACE) --> __LOG(LL_TRACE) --> LOG_LL_TRACE().
ps: suppose LL_TRACE must have a 0 value, do not remove it.
Two things make this code not compile on g++:
First, the error you're quoting is because you want to have this:
#define LOG(level) __LOG(level)
Notice no ##. Those hashmarks mean concatenate, but you're not concatenating anything. Just forwarding an argument.
The second error is that you have to remove
#define LL_TRACE 0
This line means you end up calling LOG(0) which expands into LOG_0 which isn't defined.
Shouldn't it be :
#define LOG(level) __LOG(level)
That works:
#include <iostream>
void LOG_TRACE() { std::cout << "reach here"; }
#define LOG_LL_TRACE LOG_TRACE
#define __LOG( level ) LOG_##level()
#define LOG(level) __LOG(level)
int main()
{
LOG( LL_TRACE );
return 0;
}
I want to profile my execution in a non-standard way. Using gprof, Valgrind, Oprofile... for a given function, I only get the mean of its execution time. What I would like is to obtain the standard deviation of this execution time.
Example:
void a()
sleep ( rand() % 10 + 10 )
void b()
sleep ( rand() % 14 + 2 )
main
for (1 .. 100)
a()
b()
With standard tools, a and b functions will have similar behaviour. Do you know any tool which could give me this result, with an automatic approach.
I already tested with TAU, but until now, it is not really relevant. I think there is a solution in this way, but I am not enough confident with TAU. If anyone is Tau expert, I try to keep all the function execution times, and do the math at the end. But I don't know how to specify it in Tau.
I want to profile C / C++ code, but if you have any lead in other programing language, I'm open.
A profiling tool is not magic, and you can roll your own for whatever purpose in a few lines.
Something like this, perhaps:
// code profile.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
class cProfile
{
public:
// construct profiler for a particular scope
// call at begining of scope to be timed
// pass unique name of scope
cProfile( const char* name )
{
myName = string( name );
QueryPerformanceCounter( (LARGE_INTEGER *)&myTimeStart );
}
// destructor - automatically called when scope ends
~cProfile();
// constructor - produces report when called without parameters
cProfile();
private:
typedef accumulator_set<__int64, stats<tag::variance(lazy)> > acc_t;
static map < string, acc_t > myMap;
string myName;
__int64 myTimeStart;
};
map < string, accumulator_set<__int64, stats<tag::variance(lazy)> > > cProfile::myMap;
cProfile::~cProfile()
{
__int64 t=0;
QueryPerformanceCounter( (LARGE_INTEGER *)&t );
t -= myTimeStart;
map < string, acc_t >::iterator p = myMap.find( myName );
if( p == myMap.end() ) {
// this is the first time this scope has run
acc_t acc;
pair<string,acc_t > pr(myName,acc);
p = myMap.insert( pr ).first;
}
// add the time of running to the accumulator for this scope
(p->second)( t );
}
// Generate profile report
cProfile::cProfile()
{
__int64 f;
QueryPerformanceFrequency( (LARGE_INTEGER *)&f );
printf("%20s Calls\tMean (secs)\tStdDev\n","Scope");
for( map < string, accumulator_set<__int64, stats<tag::variance(lazy)> > >::iterator p = myMap.begin();
p != myMap.end(); p++ )
{
float av = mean(p->second) / f;
float stdev = sqrt( ((double) variance(p->second)) ) / f;
printf("%20s %d\t%f\t%f\n",p->first.c_str(),
boost::accumulators::count(p->second), av, stdev);
}
}
void a()
{
cProfile profile("a");
Sleep ( rand() % 10 + 10 );
}
void b()
{
cProfile profile("b");
Sleep ( rand() % 20 + 5 );
}
int _tmain(int argc, _TCHAR* argv[])
{
for (int k=1;k<=100;k++) {
a();
b();
}
cProfile profile_report;
return 0;
}
Which produces
Scope Calls Mean (secs) StdDev
a 100 0.014928 0.002827
b 100 0.015254 0.005671
Maybe does not apply, as it's gcc-specific, but I had found this save me a couple of
times at least. If you compile the code with "-finstrument-functions" flag, then every entry and exit point of a function in the module that was compiled with this flag, will be stubbed with the calls to instrument functions. All you have to do is to have an inline that would read some high-precision counter (e.g. rdtsc on x86, though see this discussion) and a large array of records: [ func_addr, is_enter, timer_value ] to which you would continually write in the instrument functions. Upon exit, dump this array to file and analyze offline.
Quite far from "automated" approach, that you probably were looking for - but hope this is of use. The sample below shows the behaviour of gcc if it is compiled with -finstrument-functions. If you do not include the flag, it will work "as normal".
#include <stdio.h>
#include <stdlib.h>
void __cyg_profile_func_enter(void *fn, void *call)
__attribute__ ((no_instrument_function));
void __cyg_profile_func_exit(void *fn, void *call)
__attribute__ ((no_instrument_function));
void __cyg_profile_func_enter(void *fn, void *call) {
printf("Enter %x,%x\n",fn,call);
}
void __cyg_profile_func_exit(void *fn, void *call) {
printf("Exit %x,%x\n",fn,call);
}
int foo(int i) {
printf("inside foo\n");
}
int main(int argc, char *argv[]) {
printf("inside main 1\n");
foo(123);
printf("inside main 2\n");
exit(0);
}
I think Apple's Shark profiling tool can generate the mean for each function. Of course, that only helps you on a Mac.
Actually Oprofile can profile function from a call graph view, which means same callee routine with different caller will be profiled in different stats.
Try opreport command for the report.
I'd like to make a debug logging function with the same parameters as printf. But one that can be removed by the pre-processor during optimized builds.
For example:
Debug_Print("Warning: value %d > 3!\n", value);
I've looked at variadic macros but those aren't available on all platforms. gcc supports them, msvc does not.
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:
#include <stdio.h>
void XTrace0(LPCTSTR lpszText)
{
::OutputDebugString(lpszText);
}
void XTrace(LPCTSTR lpszFormat, ...)
{
va_list args;
va_start(args, lpszFormat);
int nBuf;
TCHAR szBuffer[512]; // get rid of this hard-coded buffer
nBuf = _vsnprintf(szBuffer, 511, lpszFormat, args);
::OutputDebugString(szBuffer);
va_end(args);
}
Then a typical #ifdef switch:
#ifdef _DEBUG
#define XTRACE XTrace
#else
#define XTRACE
#endif
Well that can be cleaned up quite a bit but it's the basic idea.
This is how I do debug print outs in C++. Define 'dout' (debug out) like this:
#ifdef DEBUG
#define dout cout
#else
#define dout 0 && cout
#endif
In the code I use 'dout' just like 'cout'.
dout << "in foobar with x= " << x << " and y= " << y << '\n';
If the preprocessor replaces 'dout' with '0 && cout' note that << has higher precedence than && and short-circuit evaluation of && makes the whole line evaluate to 0. Since the 0 is not used the compiler generates no code at all for that line.
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:
int debug_printf( const char *fmt, ... );
#if defined( DEBUG )
#define DEBUG_PRINTF(x) debug_printf x
#else
#define DEBUG_PRINTF(x)
#endif
DEBUG_PRINTF(( "Format string that takes %s %s\n", "any number", "of args" ));
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.
Ah, vsprintf() was the thing I was missing. I can use this to pass the variable argument list directly to printf():
#include <stdarg.h>
#include <stdio.h>
void DBG_PrintImpl(char * format, ...)
{
char buffer[256];
va_list args;
va_start(args, format);
vsprintf(buffer, format, args);
printf("%s", buffer);
va_end(args);
}
Then wrap the whole thing in a macro.
Another fun way to stub out variadic functions is:
#define function sizeof
#CodingTheWheel:
There is one slight problem with your approach. Consider a call such as
XTRACE("x=%d", x);
This works fine in the debug build, but in the release build it will expand to:
("x=%d", x);
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:
Make the XTrace function return an int (just return 0, the return value doesn't matter)
Change the #define in the #else clause to:
0 && XTrace
Now the release version will expand to:
0 && XTrace("x=%d", x);
and any decent optimizer will throw away the whole thing since short-circuit evaluation would have prevented anything after the && from ever being executed.
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.
In C++ you can use the streaming operator to simplify things:
#if defined _DEBUG
class Trace
{
public:
static Trace &GetTrace () { static Trace trace; return trace; }
Trace &operator << (int value) { /* output int */ return *this; }
Trace &operator << (short value) { /* output short */ return *this; }
Trace &operator << (Trace &(*function)(Trace &trace)) { return function (*this); }
static Trace &Endl (Trace &trace) { /* write newline and flush output */ return trace; }
// and so on
};
#define TRACE(message) Trace::GetTrace () << message << Trace::Endl
#else
#define TRACE(message)
#endif
and use it like:
void Function (int param1, short param2)
{
TRACE ("param1 = " << param1 << ", param2 = " << param2);
}
You can then implement customised trace output for classes in much the same way you would do it for outputting to std::cout.
What platforms are they not available on? stdarg is part of the standard library:
http://www.opengroup.org/onlinepubs/009695399/basedefs/stdarg.h.html
Any platform not providing it is not a standard C implementation (or very, very old). For those, you will have to use varargs:
http://opengroup.org/onlinepubs/007908775/xsh/varargs.h.html
Part of the problem with this kind of functionality is that often it requires
variadic macros. These were standardized fairly recently(C99), and lots of
old C compilers do not support the standard, or have their own special work
around.
Below is a debug header I wrote that has several cool features:
Supports C99 and C89 syntax for debug macros
Enable/Disable output based on function argument
Output to file descriptor(file io)
Note: For some reason I had some slight code formatting problems.
#ifndef _DEBUG_H_
#define _DEBUG_H_
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include "stdarg.h"
#include "stdio.h"
#define ENABLE 1
#define DISABLE 0
extern FILE* debug_fd;
int debug_file_init(char *file);
int debug_file_close(void);
#if HAVE_C99
#define PRINT(x, format, ...) \
if ( x ) { \
if ( debug_fd != NULL ) { \
fprintf(debug_fd, format, ##__VA_ARGS__); \
} \
else { \
fprintf(stdout, format, ##__VA_ARGS__); \
} \
}
#else
void PRINT(int enable, char *fmt, ...);
#endif
#if _DEBUG
#if HAVE_C99
#define DEBUG(x, format, ...) \
if ( x ) { \
if ( debug_fd != NULL ) { \
fprintf(debug_fd, "%s : %d " format, __FILE__, __LINE__, ##__VA_ARGS__); \
} \
else { \
fprintf(stderr, "%s : %d " format, __FILE__, __LINE__, ##__VA_ARGS__); \
} \
}
#define DEBUGPRINT(x, format, ...) \
if ( x ) { \
if ( debug_fd != NULL ) { \
fprintf(debug_fd, format, ##__VA_ARGS__); \
} \
else { \
fprintf(stderr, format, ##__VA_ARGS__); \
} \
}
#else /* HAVE_C99 */
void DEBUG(int enable, char *fmt, ...);
void DEBUGPRINT(int enable, char *fmt, ...);
#endif /* HAVE_C99 */
#else /* _DEBUG */
#define DEBUG(x, format, ...)
#define DEBUGPRINT(x, format, ...)
#endif /* _DEBUG */
#endif /* _DEBUG_H_ */
Have a look at this thread:
How to make a variadic macro (variable number of arguments)
It should answer your question.
This is what I use:
inline void DPRINTF(int level, char *format, ...)
{
# ifdef _DEBUG_LOG
va_list args;
va_start(args, format);
if(debugPrint & level) {
vfprintf(stdout, format, args);
}
va_end(args);
# endif /* _DEBUG_LOG */
}
which costs absolutely nothing at run-time when the _DEBUG_LOG flag is turned off.
This is a TCHAR version of user's answer, so it will work as ASCII (normal), or Unicode mode (more or less).
#define DEBUG_OUT( fmt, ...) DEBUG_OUT_TCHAR( \
TEXT(##fmt), ##__VA_ARGS__ )
#define DEBUG_OUT_TCHAR( fmt, ...) \
Trace( TEXT("[DEBUG]") #fmt, \
##__VA_ARGS__ )
void Trace(LPCTSTR format, ...)
{
LPTSTR OutputBuf;
OutputBuf = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, \
(size_t)(4096 * sizeof(TCHAR)));
va_list args;
va_start(args, format);
int nBuf;
_vstprintf_s(OutputBuf, 4095, format, args);
::OutputDebugString(OutputBuf);
va_end(args);
LocalFree(OutputBuf); // tyvm #sam shaw
}
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.
Largely derived from MSDN: Retrieving the Last-Error Code
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.
And can even display values of STL's nicely , given that you overload output operator for them
#define show(args...) describe(#args,args);
template<typename T>
void describe(string var_name,T value)
{
clog<<var_name<<" = "<<value<<" ";
}
template<typename T,typename... Args>
void describe(string var_names,T value,Args... args)
{
string::size_type pos = var_names.find(',');
string name = var_names.substr(0,pos);
var_names = var_names.substr(pos+1);
clog<<name<<" = "<<value<<" | ";
describe(var_names,args...);
}
Sample Use :
int main()
{
string a;
int b;
double c;
a="string here";
b = 7;
c= 3.14;
show(a,b,c);
}
Output :
a = string here | b = 7 | c = 3.14
Having come across the problem today, my solution is the following macro:
static TCHAR __DEBUG_BUF[1024];
#define DLog(fmt, ...) swprintf(__DEBUG_BUF, fmt, ##__VA_ARGS__); OutputDebugString(__DEBUG_BUF);
You can then call the function like this:
int value = 42;
DLog(L"The answer is: %d\n", value);