What does `##` mean in C? - c
This is an excerpt from linux kernel source. What is the stem## usage? seeing for first time in c
#define __pcpu_size_call_return(stem, variable) \
({ typeof(variable) pscr_ret__; \
__verify_pcpu_ptr(&(variable)); \
switch(sizeof(variable)) { \
case 1: pscr_ret__ = stem##1(variable);break; \
case 2: pscr_ret__ = stem##2(variable);break; \
case 4: pscr_ret__ = stem##4(variable);break; \
case 8: pscr_ret__ = stem##8(variable);break; \
default: \
__bad_size_call_parameter();break; \
} \
pscr_ret__; \
})
The preprocessor operator ## provides a way to concatenate actual arguments during macro expansion. If a parameter in the replacement text is adjacent to a ##, the parameter is replaced by the actual argument, the ## and surrounding white space are removed, and the result is re-scanned. For example, the macro paste concatenates its two arguments:
#define paste(front, back) front ## back
so paste(name, 1) creates the token name1.
The ## operator is a preprocessor operation which glues together tokens to form a single token.
So say you want to call two functions based on a common prefix, passing a single argument each time and allowing it to be changed.
You cannot use:
#define CallBoth(pref,arg) \
{ \
arg = pref A (arg); \
arg = pref B (arg); \
}
because the substituted pref and A (or B) will be distinct tokens. Similarly, you cannot use:
#define CallBoth(pref,arg) \
{ \
arg = prefA (arg); \
arg = prefB (arg); \
}
because no substitution of prefA or prefB will take place.
To do this, you use:
#define CallBoth(pref,arg) \
{ \
arg = pref##A(arg); \
arg = pref##B(arg); \
}
and the substituted pref and A (or B) are concatenated into a single token. That way, if you enter:
CallBoth(xyzzy,intVar);
it will be translated to:
{
intVar = xyzzyA(intVar);
intVar = xyzzyB(intVar);
}
Without this feature, there's no way to end up with a single token representing the function name.
As stated in a comment in the file you're referencing:
/* Branching function to split up a function into a set of functions that are called for different scalar sizes of the objects handled. */
So, depending on the size of the variable being given to the macro, it will call one of:
stem1(variable)
stem2(variable)
stem4(variable)
stem8(variable)
where stem and variable are supplied as a parameter to the macro. Or it will call __bad_size_call_parameter() if none of those sizes are relevant.
So, a call:
char char_var;
__pcpu_size_call_return(xyzzy,char_var)
will result in a call:
xyzzy1(char_var):
int int_var;
__pcpu_size_call_return(xyzzy,int_var)
will result in a call:
xyzzy4(int_var)
where sizeof(int) == 4.
Related
Default arguments to C macros
Suppose I have function bshow() with signature void bshow(int arg0, int arg1, int arg2); but for arbitrary reasons I want to implement it as a macro. Furthermore, I want the function have default arguments int arg0=0x10; int arg1=0x11; int arg2=0x12; I've already done this for the case that bshow() is a function, using the standard tricks. But how can I do it as a macro? Eg. suppose I have a macro nargs() that uses the C Preprocessor to count the number of arguments. Eg. nargs() // get replaced by 0 by the preprocessor nargs(a) // get replaced by 1 by the preprocessor nargs(a,b) // get replaced by 2 by the preprocessor I'd like to do something like (which doesn't work): #define arg0_get(a0,...) a0 #define arg1_get(a0,a1,...) a1 #define arg2_get(a0,a1,a2,...) a2 #define bshow(...) do{ \ int arg0=0x10; if(0<nargs(__VA_ARGS__)) arg0 = arg0_get(__VA_ARGS__); \ int arg1=0x11; if(1<nargs(__VA_ARGS__)) arg1 = arg1_get(__VA_ARGS__); \ int arg2=0x12; if(2<nargs(__VA_ARGS__)) arg2 = arg2_get(__VA_ARGS__); \ /* do stuff here */ \ }while(0) Actually I've already implemented the bshow() function as a macro, as follows (here it has the actual number of arguments): #define __bshow(bdim,data, nbits,ncols,base)({ \ bdim,data, nbits,ncols,base; \ putchar(0x0a); \ printf("nbits %d\n",nbits); \ printf("ncols %d\n",ncols); \ printf("base %d\n",base); \ }) #define _bshow(bdim,data, nbits,ncols,base, ...) __bshow(bdim,data, nbits,ncols,base) #define bshow(...) \ if( 2==nargs(__VA_ARGS__)) _bshow(__VA_ARGS__, 32,24,16,0,__VA_ARGS__); \ else if(3==nargs(__VA_ARGS__)) _bshow(__VA_ARGS__, 24,16,0,__VA_ARGS__); \ else if(4==nargs(__VA_ARGS__)) _bshow(__VA_ARGS__, 16,0,__VA_ARGS__); \ else if(5==nargs(__VA_ARGS__)) _bshow(__VA_ARGS__, 0,__VA_ARGS__); \ // test bshow(0,1); bshow(0,1, 10); bshow(0,1, 10,11); bshow(0,1, 10,11,12); EDIT: The proposed solution doesn't have the intended effect because it seems to "instantiate" all instances of the macro, which in general has unintended consequences. But I wonder if there's a more elegant way to do it. It'd also be nice to abstract away the entire construction inside its own macro, so that one can apply it to other functions easily, as opposed to having to write the boilerplate manually for each function/macro. Also this wasn't too helpful.
I found a nice answer. What you do is you call the vfn() macro, which is (I think) a higher-order macro that returns a macro that returns the token concatenated with the number of args (in hex base, no 0-padding) and then evaluates it at the args. Or something. Eg. supposed you want to overload a macro called bshow(). You #define the macro bshow() as #define bshow() vfn(bshow,__VA_ARGS__), and you define 1 instance of bshow for each argument count (eg. #define bshow0(...), for 0 arguments, #define bshow1(...) for 1 argument, #define bshow2(...) for 2 arguments, etc.). So now, eg., bshow(0,1) returns bshow2() (because you called it with 2 arguments) evaluated at (0,1), which is _bshow(0,1, 16,32,16), and then _bshow(0,1, 16,32,16) gets evaluated too. You can check the final preprocessor output by running gcc with the -E option, but the intermediate steps are hard to understand (for me). You also need to decide on the mandatory args and the optional args. That's almost all I (sort of) understand about what's going on, although I did upload a YT tutorial a while ago on how the argument-counting works. // ---------------------------------------------------------------- // library #define __nargs100__(a00,a01,a02,a03,a04,a05,a06,a07,a08,a09,a0a,a0b,a0c,a0d,a0e,a0f,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a1a,a1b,a1c,a1d,a1e,a1f,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a2a,a2b,a2c,a2d,a2e,a2f,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a3a,a3b,a3c,a3d,a3e,a3f,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49,a4a,a4b,a4c,a4d,a4e,a4f,a50,a51,a52,a53,a54,a55,a56,a57,a58,a59,a5a,a5b,a5c,a5d,a5e,a5f,a60,a61,a62,a63,a64,a65,a66,a67,a68,a69,a6a,a6b,a6c,a6d,a6e,a6f,a70,a71,a72,a73,a74,a75,a76,a77,a78,a79,a7a,a7b,a7c,a7d,a7e,a7f,a80,a81,a82,a83,a84,a85,a86,a87,a88,a89,a8a,a8b,a8c,a8d,a8e,a8f,a90,a91,a92,a93,a94,a95,a96,a97,a98,a99,a9a,a9b,a9c,a9d,a9e,a9f,aa0,aa1,aa2,aa3,aa4,aa5,aa6,aa7,aa8,aa9,aaa,aab,aac,aad,aae,aaf,ab0,ab1,ab2,ab3,ab4,ab5,ab6,ab7,ab8,ab9,aba,abb,abc,abd,abe,abf,ac0,ac1,ac2,ac3,ac4,ac5,ac6,ac7,ac8,ac9,aca,acb,acc,acd,ace,acf,ad0,ad1,ad2,ad3,ad4,ad5,ad6,ad7,ad8,ad9,ada,adb,adc,add,ade,adf,ae0,ae1,ae2,ae3,ae4,ae5,ae6,ae7,ae8,ae9,aea,aeb,aec,aed,aee,aef,af0,af1,af2,af3,af4,af5,af6,af7,af8,af9,afa,afb,afc,afd,afe,aff,a100,...) a100 #define __nargs__(...) __nargs100__(,##__VA_ARGS__, ff,fe,fd,fc,fb,fa,f9,f8,f7,f6,f5,f4,f3,f2,f1,f0,ef,ee,ed,ec,eb,ea,e9,e8,e7,e6,e5,e4,e3,e2,e1,e0,df,de,dd,dc,db,da,d9,d8,d7,d6,d5,d4,d3,d2,d1,d0,cf,ce,cd,cc,cb,ca,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0,bf,be,bd,bc,bb,ba,b9,b8,b7,b6,b5,b4,b3,b2,b1,b0,af,ae,ad,ac,ab,aa,a9,a8,a7,a6,a5,a4,a3,a2,a1,a0,9f,9e,9d,9c,9b,9a,99,98,97,96,95,94,93,92,91,90,8f,8e,8d,8c,8b,8a,89,88,87,86,85,84,83,82,81,80,7f,7e,7d,7c,7b,7a,79,78,77,76,75,74,73,72,71,70,6f,6e,6d,6c,6b,6a,69,68,67,66,65,64,63,62,61,60,5f,5e,5d,5c,5b,5a,59,58,57,56,55,54,53,52,51,50,4f,4e,4d,4c,4b,4a,49,48,47,46,45,44,43,42,41,40,3f,3e,3d,3c,3b,3a,39,38,37,36,35,34,33,32,31,30,2f,2e,2d,2c,2b,2a,29,28,27,26,25,24,23,22,21,20,1f,1e,1d,1c,1b,1a,19,18,17,16,15,14,13,12,11,10,f,e,d,c,b,a,9,8,7,6,5,4,3,2,1,0) #define __vfn(name, n) name##n #define _vfn( name, n) __vfn(name, n) #define vfn( fn, ...) _vfn(fn, __nargs__(__VA_ARGS__))(__VA_ARGS__) // ---------------------------------------------------------------- // example // backend: actual implementation, 2 mandatory args, 3 optional args #define _bshow(bdim,data, ncols,nbits,base)({ \ /* do stuff here */ \ }) // "frontend", default arguments get implemented here. the suffix is the number of arguments, in hexadecimal base #define bshow2(...) _bshow(__VA_ARGS__, 16,32,16) #define bshow3(...) _bshow(__VA_ARGS__, 32,16) #define bshow4(...) _bshow(__VA_ARGS__, 16) #define bshow5(...) _bshow(__VA_ARGS__) #define bshow(...) vfn(bshow,__VA_ARGS__) // test bshow(0x100,data0); bshow(0x100,data0, 14); bshow(0x100,data0, 12,16); bshow(0x100,data0, 10, 8,2);
Check at runtime if macro was defined
During the developing of static library I met the necessity to test the library functions. The functions checks are not the problem. The main problem is to test every macro definition that the library provides. I've started with the code like /* For non-vital macro (OS/WORDSIZE detections) */ # if defined(BXI_ARCH_X32) printf(" defined : BXI_ARCH_X32\n"); # endif # if defined(BXI_ARCH_X64) printf(" defined : BXI_ARCH_X64\n"); # endif <...> /* For vital macro */ #if defined(BXI_OS) printf(" defined : BXI_OS : \"%s\"\n", BXI_OS); #else print_failed(); #endif #if defined(BXI_BITS) printf(" defined : BXI_BITS: %d\n", BXI_BITS); #else print_failed(); #endif #if defined(BXI_ARCH) printf(" defined : BXI_ARCH: \"%s\"\n", BXI_ARCH); #else print_failed(); #endif That was cool, but very time-consuming. I wanted a tool that will generate the code for me, or some trick that will allow me to autogenerate the tests via macro like this TEST_MACRO(BXI_OS) But, as you know, macro definitions can't generate #if/#else/#endif directives. I needed a solution that will not only check if the macro defined at runtime, but also print its value to output.
I've met a simillar problem and found another nice trick to implement your TEST_BXI_MACRO_EXISTS with no string.h and extra function calls: #define STRINGIZE_I(x) #x #define TEST_BXI_MACRO_EXISTS(name) (#name [0] != STRINGIZE_I(name) [0]) This trick uses the same assumption that stringized value of defined macro does not match stringized name of that macro. But for my case I only needed to check if macro is defined as a numeric constant, string literal or empty value. No function-like macros and other stuff. This is how it works: #define MACRO "Content" TEST_BXI_MACRO_EXISTS(MACRO) // translates to ("MACRO"[0] != "\"Content\""[0]) // first letter of a valid macro name can never be equal to '"' #define MACRO 3.14 TEST_BXI_MACRO_EXISTS(MACRO) // translates to ("MACRO"[0] != "3.14"[0]) // first letter of a valid macro name can never be equal to a digit #define MACRO TEST_BXI_MACRO_EXISTS(MACRO) // translates to ("MACRO"[0] != ""[0]) // first letter of a valid macro name can never be equal to a '\0' This approach can also be easily used to test whether macro defines a numeric constant, string literal or empty value like your approach does by checking the value of STRINGIZE_I(name) [0]. So far I have no idea how to test function-like macros this way, but I thought sharing this with others could be useful anyway.
But, as this is Q&A-style article, I've found the solution. The final result looks as follows: TEST_BXI_MACRO_STRING(BXI_OS); TEST_BXI_MACRO_STRING(BXI_ARCH); TEST_BXI_MACRO_I32 (BXI_BITS); TEST_BXI_MACRO_EXISTS_WEAK(BXI_ARCH_X32); // _WEAK as we don't need to fail TEST_BXI_MACRO_EXISTS_WEAK(BXI_ARCH_X64); The result: Let us see every one of them closely TEST_BXI_MACRO_STRING This one is pretty simple: #define TEST_BXI_MACRO_STRING(name) \ do \ { \ print_macro_name(#name); \ if (!TEST_BXI_MACRO_DEFINED(#name, name(1))) \ print_macro_undefined_exit(); \ if (strlen(name "") == 0) \ print_macro_undefined_exit(); \ print_macro_value_string(name ""); \ } \ while (0) We just using the idea that C allows const strings auto-concatenation. So when the macro exists we will receive #define MACRO "Content" "Content" "" = "Content" and when it doesn't "" = "" Then we look at the length of the resulting string, and when it's 0 - bingo, macro is not defined. This will NOT work for "" macro, but this special case could be checked with TEST_BXI_MACRO_EXISTS TEST_BXI_MACRO_I32 #define TEST_BXI_MACRO_I32(name) \ do \ { \ print_macro_name(#name); \ if (!TEST_BXI_MACRO_DEFINED(#name, name(1))) \ print_macro_undefined_exit(); \ if ((5 * name + 1) == 5) \ print_macro_undefined_exit(); \ print_macro_value_signed(name + 0); \ } \ while (0) NOTE: you can similarly create ...MACRO_U32 version just by replacing the printer formatter. Here we use the fact that '+' operator could be unary AND binary. Let us simulate three cases: #define MACRO (10) In this case the complete formula will look as follows: 5 * 10 + 1 => 50 + 1 => 51 #define MACRO (0) In this case the multiplication fades out: 5 * 0 + 1 => 0 + 1 => 1 In some cases you can use this for additional check if the defined macro is 0 (like for preprocessing options and stuff) #define MACRO This case shows some math magic: 5 * + 1 => 5 * (+1) => 5 * 1 => 5 As +1 is interpreted as simple 1 we receive 5. TEST_BXI_MACRO_EXISTS #define TEST_BXI_MACRO_DEFINED_I(strstr, fnc) (strcmp(#fnc, strstr "(1)")) #define TEST_BXI_MACRO_DEFINED(str, fnc) TEST_BXI_MACRO_DEFINED_I(str, fnc) #define TEST_BXI_MACRO_EXISTS(name) \ do \ { \ print_macro_name(#name); \ if (!TEST_BXI_MACRO_DEFINED(#name, name(1))) \ print_macro_undefined_exit(); \ else \ print_macro_defined(); \ } \ while (0) This implementation uses the fact that the string value of macro should not expand same as its name (as #define A A is useles) Additional functions For those who want the printing functions, here they are: void print_macro_name(const char * name) { printf(" checking: %-20s: ", name); } void print_macro_undefined_exit(void) { printf("\033[1;31mUNDEFINED\033[0m\n"); exit(1); } void print_macro_defined(void) { printf("\033[1;33mDEFINED\033[0m\n"); } void print_macro_undefined(void) { printf("\033[1;32mUNDEFINED\033[0m\n"); } void print_macro_value_string(const char * value) { printf("\"%s\"\n", value); } void print_macro_value_signed(i32 value) { printf("%d\n", value); } void print_macro_value_unsigned(u32 value) { printf("%u\n", value); }
Extract a function name inside a macro
In C, we often have to run such code if (! somefun(x, y, z)) { perror("somefun") } Is it possible to create a macro which, used as follows: #define chkerr ... chkerr(somefun(x, y, z)); would compile to the above? I already know I can use __VA_ARGS__ macro, but this would require me to call it like chkerr(somefun, x, y, z)
Short variant (you spotted already): #define chkErr(FUNCTION, ...) \ if(!FUNCTION(__VA_ARGS__)) \ { \ perror(#FUNCTION); \ } Be aware that this can impose big problems in nested if/else or similar constructs: if(x) chkErr(f, 10, 12) //; //^ semicolon forgotten! else chkErr(f, 12, 10); would compile to code equivalent to the following: if(x) { if(!f(10, 12)) perror("f"); else if(!f, 12, 10)) perror("f"); } Quite obviously not what was intended with the if/else written with the macros... So you really should prefer to let it look like a real function (requiring a semicolon): #define chkErr(FUNCTION, ...) \ do \ { \ if(!FUNCTION(__VA_ARGS__)) \ { \ perror(#FUNCTION); \ } \ } \ while(0) You would call it like this: chkErr(someFunction, 10, 12); In case of error, output would be: someFunction: <error text> However, this hides the fact that a function actually gets called, making it more difficult to understand for "outsiders". Same output, not hiding the function call, but requiring one additional comma in between function and arguments (compared to a normal function call): #define chkErr(FUNCTION, ARGUMENTS) \ do \ { \ if(!FUNCTION ARGUMENTS) \ { \ perror(#FUNCTION); \ } \ } \ while(0) chkErr(someFunction,(12, 10)); // ^ (!) Another variant with the charm of retaining the function call would print out this entire function call: #define chkErr(FUNCTION_CALL) \ do \ { \ if(!FUNCTION_CALL) \ { \ perror(#FUNCTION_CALL); \ } \ } \ while(0) chkErr(someFunction(10, 12)); In case of error, output would be: someFunction(10, 12): <error text> Addendum: If you really want exactly the output as shown in the question and still have the function call retained (without comma in between), you are a little in trouble. Actually, it is possible, but it requires some extra work: Problem is how the preprocessor operates on macro arguments: Each argument is a token. It can easily combine tokens, but cannot split them. Leaving out any commas results in the macro accepting one single token, just as in my second variant. Sure, you can stringify it, as I did, but you get the function arguments with. This is a string literal, and as the pre-processor cannot modify string literals, you have to operate on them at runtime. Next problem then is, though, string literals are unmodifiable. So you need to modify a copy! The following variant would do all this work for you: #define chkErr(FUNCTION_CALL) \ do \ { \ if(!FUNCTION_CALL) \ { \ char function_name[] = #FUNCTION_CALL; \ char* function_name_end = strchr(function_name, '('); \ if(function_name_end) \ *function_name_end = 0; \ perror(function_name); \ } \ } \ while(0) Well, decide you if it is worth the effort... By the way - whitespace between function name and opening parenthesis is not eliminated. If you want to be perfect: unsigned char* end = (unsigned char*) function_name; while(*end && *end != '(' && !isspace(*end)) ++end; *end = 0; Or, much nicer (thanks chqrlie for the hint): function_name[strcspn(function_name, "( \t")] = 0; Anything else I can think of would require an additional pre-processing step: #define CAT(X, Y) CAT_(X, Y) #define CAT_(X, Y) X ## Y #define chkErr(FUNCTION_CALL) \ do \ { \ if(!FUNCTION_CALL) \ { \ perror(CAT(CHK_ERR_TEXT_, __LINE__)); \ } \ } \ while 0 chkErr(function(10, 12)); Ah, huh, this would result in code like this: if(!function(10, 12)) { perror(CHK_ERR_TEXT_42); } And now, where to get these macros from? Well, the pre-processing, remember? Possibly a perl or python script, e. g. generating an additional header file you'd have to include. You would have to make sure this pre-processing is done every time before the compiler's pre-processor runs. Well, all not impossible to solve, but I'll leave this to the masochists among us...
C11 6.4.2.2 Predefined identifiers The identifier __func__ shall be implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration static const char __func__[] = "function-name"; appeared, where function-name is the name of the lexically-enclosing function. You can used it this way: #define chkErr(exp) do { if (!(exp)) perror(__func__); } while (0) chkerr(somefun(x, y, z)); Unfortunately, this would produce an error message with the name of the calling function, not somefun. Here is a simple variant that should work and even produce more informative error messages: #define chkErr(exp) do { if (!(exp)) perror(#exp); } while (0) chkerr(somefun(x, y, z)); In case somefun(x, y, z) returns a non zero value, the error message will contain the string "somefun(x, y, z)". You can combine both techniques to give both the offending call and the location: #include <errno.h> #include <stdio.h> #include <string.h> #define chkErr(exp) \ do { if (!(exp)) \ fprintf(stderr, "%s:%d: in function %s, %s failed: %s\n",\ __FILE__, __LINE__, __func__, #exp, strerror(errno)); \ } while (0) chkerr(somefun(x, y, z)); This assumes somefun() returns 0 or NULL in case of error and set errno accordingly. Note however that most system calls return non zero in case of error.
You can use the original call format: chkerr(somefun(x, y, z)); With a macro and a helper function: #define chkerr(fcall) \ if (!fcall) { \ perror(extract_fname(#fcall)); \ } const char *extract_fname(const char *fcall); The extract_fname function would get text and return everything until the open parenthesis.
Yes it is possible with an ugly, unsafe variadic macro: #define chkerr(func, ...) \ if(!func(__VA_ARGS__)) \ { \ perror(#func); \ } ... chkerr(somefunc, 1, 2, 3); But it is a very bad idea. Call for sanity: If there was just the original code with the plain if statement, the reader would think "Here they call a function and do some basic error control. Okay, basic stuff. Moving on...". But after the changes, anyone who reads the code will instead freeze and think "WTF is this???". You can never write a macro that is clearer than the if statement - which makes the if statement superior to the macro. Some rules to follow: Function-like macros are dangerous and unreadable. They should only be used as the very last resort. Avoid inventing your own secret macro language with function-like macros. C programmers who read your code know C. They don't know your secret macro language. "To avoid typing" is often a poor rationale for program design decisions. Avoiding code repetition is a good rationale, but taking it to the extremes will affect code readability. If you avoid code repetition and make the code more readable at the same time, it is a good thing. If you do it but the code turns less readable, it is hard to justify.
It's not possible to extract just the function name. The C processor sees the literals you pass as single tokens, which can't be manipulated. Your only options are to print the function with arguments like Aconcague suggests or pass the name as a separate parameter: #define chkErr(FUNCTION_NAME, FUNCTION_CALL) \ if(!FUNCTION_CALL) \ { \ perror(#FUNCTION_NAME); \ } chkErr(someFunction, someFunction(10, 12));
Code section as macro parameter
For a debug purpose I defined the following macro #define SECTION_TIME(out, s) GPIO_SetOut(out); \ s \ GPIO_ClrOut(out); usage: SECTION_TIME(GPIO_fooOut, foo(); bar(); foo=bar^foo;....;....; ) Goal: needed to mesure time of some code. Sometimes this macro do not compile. Did I miss understand somthing? PS: I also tried surrounding my code with {} error: macro "SECTION_TIME" passed 6 arguments, but takes just 2
When code walks like a duck and talks like a duck, it better fully behave exactly like a duck. What I mean by that is that SECTION_TIME(GPIO_fooOut, ...) (sort of) looks like one statement while in reality it maps to 3 or more statements. This is bad, and you should strive to truely make it one statement. This is actually not difficult, and the common idiom used for this is to wrap the macro content in do { ... } while (0) without a trailing semicolon (so that the trailing semicolon is supplied to the end of the macro invocation). So you should at least change your macro to something like #define SECTION_TIME(out, s) \ do { \ GPIO_SetOut(out); \ s; \ GPIO_ClrOut(out); \ } while (0) Also notice here that you should put the terminating semicolon for s in the macro and not the argument. So the macro should be invoked like SECTION_TIME(GPIO_fooOut, foo(); bar(); foo=bar^foo;....;.... ); Depending on use cases, the suggestion to use SETION_TIME_BEGIN and SECTION_TIME_END might be a better solution.
Solved using variadic macro #define BOARD_SECTION_TIME(out, ...) do { \ GPIO_SetOut(out); \ __VA_ARGS__ \ GPIO_ClrOut(out); \ } while(0)
I also use the way of __VA_ARGS__ but I also make some curry-like syntax by defining a second macro, which name is in the first: #define SECTION_TIME(out) \ do { \ /* remember to save the value, so that the same output is always cleared and can be used in the second one */ \ decltype(out) _o = out; \ GPIO_SetOut(_o); \ SECTION_TIME_BLOCK1 #define SECTION_TIME_BLOCK1(...) \ {__VA_ARGS__}; \ GPIO_ClrOut(_o); \ } while(0); And it can be used like this: SECTION_TIME(GPIO_fooOut) ( foo(); bar(); foo=bar^foo; //....;....; ); You see that the out input-parameter is a separate tuple and that the syntax is similar to the syntax of if for example, only the brackets are different. And if you want to define only one macro, you say that the code-parameter(s) should be in a tuple: // this macro is only a help to remove the brackets and can be used in multiple definitions #define PP_REMOVE_BRACKETS(...) __VA_ARGS__ /** * \param code a tuple containing the code you want to run **/ #define SECTION_TIME(out, code) \ do { \ /* remember to save the value, so that the same output is always cleared */ \ decltype(out) _o = out; \ GPIO_SetOut(_o); \ {PP_REMOVE_BRACKETS code}; \ GPIO_ClrOut(_o); \ } while(0); This can be used like this: SECTION_TIME(GPIO_fooOut, ( foo(); bar(); foo=bar^foo; //....;....; ));
Using and returning output in C macro
I'm trying to instrument some code to catch and print error messages. Currently I'm using a macro somethng like this: #define my_function(x) \ switch(function(x)) { \ case ERROR: \ fprintf(stderr, "Error!\n"); \ break; \ } Normally, I never capture the function output and this works fine. But I've found a couple cases where I also need the return value of function(). I tried something like the following, but this produces a syntax error. #define my_function(x) \ do { \ int __err = function(x); \ switch(__err) { \ case ERROR: \ fprintf(stderr, "Error!\n"); \ break; \ } \ __err; \ } while(0) I could declare a global variable to hold the return value of the function, but that looks ugly and my program is multithreaded, so that's likely to cause problems. I'm hoping there's a better solution out there.
GCC has a feature called statement expressions So if define macro like #define FOO(A) ({int retval; retval = do_something(A); retval;}) then you will be able to use it like foo = FOO(bar);
This is relatively complicated code, there is not much reason to have it in a macro. Make it inline (C99) or static (C89) or both if you really want to place it in a header file. With any reasonable compiler this then should result in the same efficiency as a macro.
A very late reply. But none the less. I agree inline functions are better but MACROs do offer some pretty printing fun you can't get with inline functions. I agree with #qrdl that you can indeed use statement expressions had you restructured your statements a bit. Here is how it would work with a macro - #define my_function(x, y) ({ \ int __err = 0; \ do { \ __err = function(x, y); \ switch(__err) { \ case ERROR: \ fprintf(stderr, "Error!\n"); \ break; \ } \ } while(0); \ __err; \ })
Sorry, this is an edit... I think you just need the curly braces. No need for the do..while keywords Make sure that the backslashes are the last characters on each line (no space after). If you need to get the err value out of the macro, you can just add a parameter Like so: #define my_function(x, out) \ { \ int __err = function(x); \ switch(__err) { \ case ERROR: \ fprintf(stderr, "Error!\n"); \ break; \ } \ __err; \ (*(out)) = _err; \ } To preserve the pass-by-reference C paradigm, you should call my_function this way: int output_err; my_function(num, &output_err); This way, later, if you decide to make my_function a real function, you don't need to change the call references. Btw, qrdl's "Statement Expressions" is also a good way to do it.
there is no need to declare variable if your function is returning something then you can directly get that value. For example: #define FOO(A) do_something(A) Here do_something returns some integer. Then you can easily use it like: int a = FOO(a);