I have incorporated libiniparser
library in to my Android NDK application. One problem this library write logs directly to stdout
/ stderr
.
I did not want to heavily modify the code so I wrote a macro to log in logcat
#include <android/log.h>
#define LOG_TAG "libinipaser"
#define fprintf(pipe,...) \
if (pipe == stdout) \
__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__); \
else if (pipe == stderr) \
__android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__); \
else \
fprintf(pipe,__VA_ARGS__)
Until the last moment I was not sure it would work, but it works. I have checked preprocessor output (gcc -E) it looks like I expected
fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]);
line above after preprocessing looks:
if (f == (&__sF[1])) __android_log_print(ANDROID_LOG_INFO,"libinipaser","[%s]=[%s]\n", d->key[i], d->val[i]); else if (f == (&__sF[2])) __android_log_print(ANDROID_LOG_ERROR,"libinipaser","[%s]=[%s]\n", d->key[i], d->val[i]); else fprintf(f,"[%s]=[%s]\n", d->key[i], d->val[i]);
Could someone explain:
LOG_TAG
define was replaced but inner fprintf
wasn't? I'll answer question 4 only. mstorsjo has the rest pretty much taped.
No. It's not really a good idea. Macro Magic is generally discouraged where there's another 'proper' way to achieve the result - that might be a constant or a function (as in this case).
In this case what appears to be a call to fprintf
that (normally) returns an int
(the count of characters output) will not evaluate to that. For example, int count=fprintf(file,"Hello");
will be a compilation error.
That might not be a problem for you, but considering the general case, anyone who has any code in a translation unit including that macro definition may have just had their code broken and have a Dickens of a job finding the cause and then need to #undefine
the macro to get their code back!
Marcos aren't bad. They definitely have their place in conditional compilation and debugging in particular. Personally I miss them for that purpose in Java.
However, as a general rule, if there's another language construct to do the same thing - use it.
There's some excellent answers discussing the merits and dismerits of macros here:
Why are preprocessor macros evil and what are the alternatives?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.