Reputation: 1918
In my C++-code there are several fprintf-statements, which I have used for debugging. Since I might need them again, I would prefer not to comment them out for the moment. However, I need the execution of the program to be fast, so I would like to avoid them being printed out, as they are for the moment (I redirected stderr to a file).
Preferably this would be determined by the user passing an argument to the program, which I would extract like this:
main (int argc, char *argv[])
{
int isPrint=0;
if (argc > 1 ) {
isPrint = atoi ( argv[2]);
}
}
I thought of renaming fprintf to another name, and then from that function do a fprintf-call using the same parameters, based on the value of isPrint; however, then I realized that fprintf can have so many different kind of arguments and a various number of arguments; and that I don't know any generic way of declaring my own function with those requirements.
So I wonder how to create a function,which works exactly like fprintf, but which takes the extra parameter isPrint; or how to solve the above problem in another way.
Complementary information after first post: One solution would be to add this before each fprintf-statement:
if (isPrint == true )
Upvotes: 0
Views: 136
Reputation: 10497
It depends how much flexibilty you've got in changing the code and whether you want to be able to switch this off at runtime or just compile time.
I'd suggest you wrap it in your own variadic function (for tips look here) and then you've encapsulated the functionality.
Your function will essentially be just a thin wrapper round fprintf()
but at this point you can then either use the preprocessor to ensure that your logging function does nothing if you compile it out, or you can do an integer comparison with, say, a logging level at runtime so that the underlying fprintf()
only gets called if your debugging level is high enough.
Upvotes: 0
Reputation: 399959
The typical approach is to use the preprocessor to compile away the calls to fprintf()
.
You would do something like this:
#if defined DEBUG
#define LOG(a) fprintf a
#else
#define LOG(a)
#endif
And in the code you would do:
LOG(("The value is %f", some_variable));
Note the double parenthesis, that's just to make the syntax work. You can do it nicer, but this is simpler to explain.
Now, you would either just edit the code to #define
or #undef
the DEBUG
preprocessor symbol at the top of the file, or pass suitable options to the compiler (-D
for GCC).
Upvotes: 5
Reputation: 5966
First note that if this is just for debugging, I'd agree that the typical way is to use macros or preprocessor defines to tell the compiler to include logging or not.
However, if you don't want it removed entirely by the compiler (so that you can turn the printing on or off with an argument), you could write your own log function that takes isPrint
and some string, and then use snprintf()
to format the string before you call it.
Something along these lines:
void myLog(int isPrint, char *message)
{
if(isPrint == 1)
{
fprintf(logFile, "%s", message);
}
}
char msg[64];
snprintf(msg, 64, "Test Message %d", 10);
myLog(isPrint, msg);
It may also be possible to wrap fprintf()
in your own varags function, but that would be more complicated.
Upvotes: 1
Reputation: 70030
For debugging purpose you can use the variable argument macro:
#ifdef DEBUG
#define FPRINTF(...) fprintf(__VA_ARGS__)
#else
#define FPRINTF(...)
#endif
Be attentive that, if you use fprintf
directly instead of FPRINTF
then since you are defining a library function, it should appear after #include<>
of that function.
Upvotes: 1