While reading codes of my group project, I come across many DEFINEs, and some of them seems strange. To generalize it, please look at the following 2 examples.
Example 1:
#define SNPRINTF(dst, fmt, arg...) snprintf(dst, 开发者_JS百科sizeof(dst), fmt, ##arg)
what does "##" means in this circumstance? I've tried to delete both of them, and write codes like "char buf[1024]; SNPRINTF(buf,"%s,%s","abcd","efg");" which produced the same result. So "##" seems no use and no harm to me.
Example 2:
#define CLOSE(fd) do { \
if (-1 != (fd)) { \
close(fd); \
(fd) = -1; \
} \
} while (0)
Necessary to stuff the inner code to the do{}while(0)
statement? What's the use?
The ...
identify a variadic macro per the C99 standard. The token to indicate expansion of "all remaining argument" in the right hand side, per the standard, is __VA_ARGS__
-- I imagine you're using some C compiler with a non-standard extension that allows the different forms you're using (##
is the preprocessor token-pasting operator, but I don't see how that applies here).
The second form is a classic trick (older even than C89) to ensure a ;
after the macro behaves correctly, an else
after it doesn't bind to the wrong if
, and so on. Basically, wrapping the multiple and conditional statements needed in that do
...while
safely "nests" them inside a block that requires a semicolon afterwards, syntactically "just as if" the macro invocation was instead a function call.
Two answer your questions in order:
is the pasting operator, and so its not really doing anything there. I think (couldn't find any references) that there are non-standard versions of it that will eat a preceding comma if its empty, so maybe that's what this is for.
- As already mentioned, the
do{...}while(0)
thing is a standard trick to ensure that whatever gets pasted into the...
can be treated as a single statement. It generally lets you write things like:
if( floon )
CLOSE(floon);
without worrying about it.
精彩评论