c token pasting (concatenation) with empty string - c

I'm trying to use macro for c code.
However, I stuck in using token concatenation
I have below variables.
A, aA, bA, cA ...
And, all of these variables used for same function (situation is a bit complicate, so just passing variable is not enough).
If I have only
aA, bA, cA
Then, I can do using the below macro.
#define CALL_FUNCTION(GROUP) \
FUNCTION(GROUP##A);
However, because of
A
I can't use the mentioned macro anymore.
I tried,
#define CALL_FUNCTION(GROUP) \
FUNCTION(GROUP##A);
FUNCTION(NULL);
FUNCTION(a);
FUNCTION(b);
FUNCTION(c);
But actually, NULL is not empty string, it didn't work.
FUNCTION("");
Also didn't work.
There are alternative way like,
#define CALL_FUNCTION(GROUP) \
if(GROUP == NULL)\
FUNCTION(A);\
else\
FUNCTION(GROUP##A);
However, in this case, I need to write few lines more.
In my case, it cause much more codes.
I googled a lot, but I couldn't solution.
Is there anyone who knows how to token paste with empty string?
Thanks

Pass an empty argument and it will effectively concatenate nothing with A, producing just A:
#define CALL_FUNCTION(GROUP) \
FUNCTION(GROUP##A);
CALL_FUNCTION() // expands to FUNCTION(A);
CALL_FUNCTION(a) // expands to FUNCTION(aA);
You can see this work live.
The thing to note is that when you call CALL_FUNCTION(), you do not pass zero arguments, as you do with functions. Instead, you pass a single argument - empty. Similarly, MACRO(,) calls MACRO with two empty arguments. It just so happens that the concatenation behaviour with empty is what you want.

You just need a second macro that takes no parameters:
#define CALL_FUNCTION() \
FUNCTION(A);
#define CALL_FUNCTION(GROUP) \
FUNCTION(GROUP##A);
Example:
#include <stdio.h>
#define FUNCTION(x) printf( # x "\n" )
#define CALL_FUNCTION() FUNCTION(A)
#define CALL_FUNCTION(GROUP) FUNCTION(GROUP##A)
int main(void) {
CALL_FUNCTION();
CALL_FUNCTION(a);
CALL_FUNCTION(b);
CALL_FUNCTION(c);
return 0;
}
Output:
A
aA
bA
cA

Related

C - X Macro Self Iteration / Expansion

I am curious if any of you can think of a way upon macro expansion to repeat the macro itself. Here is an incredibly small scale version of an overall bigger problem:
#include<stdio.h>
#define LETTERS\
X(A)\
X(B)\
X(C)\
X(D)
#define X(L) #L
int main(int nargs,char** args)
{
printf("%s\n",LETTERS);
return 0;
}
Output: ABCD
Desired output: AABCD BABCD CABCD DABCD
The desired output is clearly similar to a nested (N^2) loop over whatever input data.
The stringification doesn't matter, it's only there for compilation.
There are some obvious and some not so obvious solutions to the desired output.
One is to make a complete copy of the macro, then between each X element, you simply refer to the copy. This would be wasteful and I don't want to do it. Obviously you can't refer to the macro itself due to recursion. I have made many attempts to find a decent solution, and won't list all of them as it would take up way too much time. I am open to solutions that use other macros to repeat or expand the original, or solutions that use janky forms of recursion.
#include<stdio.h>
#define LETTERS_COPY\
X(A)\
X(B)\
X(C)\
X(D)
#define LETTERS\
X(A)\
LETTERS_COPY\
X(B)\
LETTERS_COPY\
X(C)\
LETTERS_COPY\
X(D)\
LETTERS_COPY
#define X(L) #L
int main(int nargs,char** args)
{
printf("%s\n",LETTERS);
return 0;
}
Again, this builds just fine and works, but requires a complete duplicate of the original data, interjecting itself between each X element.
If you use an iterating macro, like how one is defined in the P99 macro utility collection, then it becomes much easier to solve.
Since we intend to define an iterating macro, we don't need X-macros on the letters anymore.
#define LETTERS \
A \
,B \
,C \
,D
Below is a simplified iterating macro that supports up to 5 arguments. Hopefully you see how to extend the implementation if you need more.
#define XX(X, ...) \
XX_X(__VA_ARGS__, XX_5, XX_4, XX_3, XX_2, XX_1) \
(X, __VA_ARGS__)
#define XX_X(_1,_2,_3,_4,_5,X,...) X
#define XX_1(X, _) X(_)
#define XX_2(X, _, ...) X(_) XX_1(X, __VA_ARGS__)
#define XX_3(X, _, ...) X(_) XX_2(X, __VA_ARGS__)
#define XX_4(X, _, ...) X(_) XX_3(X, __VA_ARGS__)
#define XX_5(X, _, ...) X(_) XX_4(X, __VA_ARGS__)
So, if you invoke XX(X, LETTERS), it will expand into the X-macro version of LETTERS you had before.
The magic of the XX() macro is the meta nature of the XX_X() macro, which selects the right numeric macro to use. The numeric macro is passed in reverse order to the XX_X() macro when it is invoked by XX(). This makes it so that XX_X() selects a lower numeric macro if __VA_ARGS__ contains fewer arguments.
Now, we create a macro to turn the argument into a string:
#define STR(X) STR_(X)
#define STR_(X) #X
This allows you to easily create the string with all your letters.
And printing your iterative output just needs another macro.
int main () {
const char *letters = XX(STR, LETTERS);
#define LETTERS_PRINT(X) printf("%s%s\n", #X, letters);
XX(LETTERS_PRINT, LETTERS)
}
We see that the solution applies XX() twice. Once to create the string of all your letters. Once to create the output, which is prepending each letter to the combined letters.
Try it online!
For anyone wondering, the best I could do was make a second X macro that takes 2 args, and the outer list becomes a function macro that takes a single arg. This lets you pass data to the list, and to the second x macro, while still being able to unpack either X macro however you like.
#include<stdio.h>
#define _CAT(A,B) A##B
#define CAT(A,B) _CAT(A,B)
#define _STR(S) #S
#define STR(S) _STR(S)
#define LETTERS(L)\
XX(L,X(A))\
XX(L,X(B))\
XX(L,X(C))\
XX(L,X(D))
int main(int nargs,char** args)
{
#define X(L) L
#define XX(L1,L2) STR(CAT(L1,L2))
printf("%s\n",LETTERS(A));
printf("%s\n",LETTERS(B));
printf("%s\n",LETTERS(C));
printf("%s\n",LETTERS(D));
#undef XX
#undef X
return 0;
}

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);

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));

Using typeof to convert a variable declaration to a type?

Currently, I have a scenario much like this:
#define my_macro(var) __builtin_types_compatible_p(typeof(var), foo) ? do_something : do_something_else
However, inadvertently the macro gets passed this parameter:
my_macro(int x);
Which of course fails, because typeof(int x) isn't valid.
Is there a transformation I can apply inside the my_macro which will allow typeof to work on that expression? I cannot change what is passed into the macro, only what happens inside the macro.
So, something like this:
#define my_macro(var) typeof(?? var ??)
Or, is there another expression I should be using here?
Well, I found a way to do it, using yet another GCC extension, this time the statement expression:
#define my_typeof(definition) typeof(({ definition, _def; _def; }))
Which, of course, expands to:
typeof(({ int x, _def; _def; }))
Pretty ugly, but why do I care? It works.
You could handle x or int x separately but to handle both with one macro you would need the ability to parse/separate a space-delimited argument within the C preprocessor. To my knowledge, no such support exists in the C preprocessor. Without such parsing capabilities you must find some other clever way to write a macro that works around this limitation, for example, something in the spirit of my_macro2() in the following code sample:
#include <stdio.h>
#define my_macro1(var) \
do { \
typeof(var) blah; \
printf("sizeof(var)=%d\n", sizeof(blah)); \
} while(0)
#define my_macro2(var) \
do { \
var, newvar_sametype; \
typeof(newvar_sametype) blah; \
printf("sizeof(newvar_sametype)=%d\n", sizeof(blah)); \
} while(0)
int
main()
{
int x;
my_macro1(x);
my_macro2(char y);
return 0;
}

Detecting null parameter in preprocessor macro

I have the following macro function in vanilla C:
#define GLOG(format_string, ...) { \
const char *file = strrchr(__FILE__, '/'); \
char format[256] = "%s:%s!%d\t"; \
strncat(format, format_string, 248); \
strcat(format, "\n"); \
printf(format, __FUNCTION__, file ? file : __FILE__, __LINE__, ##__VA_ARGS__); \
}
which lets me print a debug message containing the current function, file and line number, e.g.
GLOG("count=%d", count);
might print
do_count:counter.c!123 count=456
How can I modify the function to print all local variables if caller omits format_string? e.g.
GLOG();
might print
do_count:counter.c!123 count=456, message="Hello world", array=[7, 8] structure={ptr=0xACE0FBA5E, coord={x=9, y=0}}
If that's not possible, how can I modify it to print just the current function, file and line number? e.g.
do_count:counter.c!123
As is, this returns an error:
error: expected expression before ‘,’ token
as the strncat line is simply
strncat(format, , 248);
First, inspecting all the local variables at runtime by the process itself seems impossible because C doesn't have any means for reflection.
Second, you would be much better off if you wrote the logging macro like that:
#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define GLOGF(fmt, ...) \
printf("%s:%s " fmt "\n", __func__, __FILE__ "!" TOSTRING(__LINE__), ##__VA_ARGS__)
int main (void) {
/* main:test.c!xx count=5 */
GLOGF("count=%d", 5);
/* main:test.c!xx */
GLOGF();
return 0;
}
It is simpler and doesn't incur any additional runtime overhead since the string is concatenated at compile-time.
Also note that I have used __func__ instead of __FUNCTION__, because the latter is non-standard.
I found this link in this answer. It might help you with the first part of the question.
The second, how to get all local variables, is much harder, if not impossible. The reason is that the code, when compiled, doesn't actually have variables, it just have offsets into a memory area (the stack.) It might be possible that your compiler have internal functions that can be used to inspect the stack, but then you only have possible values not the names of the variables. The only solution I see it to use special pre-processor macros to declare local variables, and then a list of structures to represent them for introspection, which will be a lot of both runtime and memory overhead.
As others here have mentioned, C does not have reflection features, and therefore you are not going to be capable of capturing the local variables in a macro call. That being said, if you want something to conditionally happen with a macro depending on if there are or are not any arguments to the macro invocation (i.e., your "non-null" and "null" arguments), then you can do something like the following:
#include <string.h>
#define NULL_IDENT ""
#define IDENT(ident_name) #ident_name
#define MACRO(ident_name) \
if (strcmp(NULL_IDENT, IDENT(ident_name)) == 0) { \
/* add code for a null argument passed to the macro */ } \
else { \
/* add code for a non-null argument passed to the macro */ }
Based on Blagovest Buyukliev's answer, I've come up with the following solution for part 2:
#define GLOG(fmt, ...) do { const char *fn = strrchr(__FILE__, '/'); \
printf("%s:%s!%d\t"fmt"\n",__func__,fn?++fn:__FILE__,__LINE__,##__VA_ARGS__);\
} while(0)
using the preprocessor's string concatenation to simply concatenate a null string if the parameter is omitted.
Additionally, I added the do {...} while(0) to swallow the trailing semicolon so that the following if...else works:
if (...)
GLOG();
else
/* do something else */
(idea from http://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html ).

Resources