1
votes

I would like to have a macro that prints it's own name (among other things), but I can't find a way to expand the macros' name in the macro itself. Basically, I want the equivalent of __FUNCTION__ for a macro name.

For example:

#define F(a, b, c) do { \
   printf("%s: %s,%s,%s\n", __MACRO__, #a, #b, #c); \
   c = a+b; b=a; \
} while(0)

F(x,y,z); 

I would like this to print "F: x,y,z" when called.


This is indeed an XY problem.

Here is really what I'm trying to do: Soft linking symbols from a library using dlopen and dlsyms.

In order to do so the typical way i know of is: 1) Include the headers from the library. 2) Declare a variable of the type of the function you are trying to import 3) Initialize said variable with a call to dlsym 4) The call the actual function through that variable instead of calling the symbol directly.

When you have many such function to soft link, it becomes very repetitive, so macro can help.

For an full fledge example of that, see here: https://github.com/WebKit/webkit/blob/master/Source/WebCore/platform/mac/SoftLinking.h

The problem in that example and others is that you still need to manually copy the parameters list for each the functions you want to soft link. I'm trying to improve on that, and was experimenting with macro tricks, one of which would have been helped by being able to answer my initial question.

--

Beside my soft linking issues, there are other situation where this could be useful. For example for debugging purpose, one might want to print some diagnostic information before or after every call to certain functions. One could do so by overriding functions names with macros:

#define funcA(...) \
printf("Before call to %s:%d - %d\n", #funcA, __LINE__, g_count); \
funcA(__VA_ARGS__) \
printf("After call to %s:%d - %d\n", #funcA, __LINE__, g_count);

This works well enough but if I want to do this for a bunch of function, I have to copy that macro and change funcA to funcB 4 times for each new macro. I'd rather copy it and just change the name of the macros, without having to change what's inside.

I can optimize the above by defining an internal macro p, similar to what Basile suggested:

#define funcA(...) WRAP(funcA, __VA_ARGS__)

But that's still means I need to change funcA to the new function name twice every time I copy the macro for another function.

1
Why do you wish to make you code unreadable and more difficult to debug? Why does some people love the pre-proccessor. It has its place for doing simple stuff.Ed Heal
Well, that example is too simple. In my actual use case, the 'printf' would actually be embedded in another macros like this #define P(f, ...) printf("%s%s\n", f, __VA_ARGS__)Droopycom
@EdHeal I'm actually trying to avoid having to copy paste a pattern a bunch of times.Droopycom
Macros are terrible to debug. They obfuscate the code. They do not have the luxury of the type mechanism that the compiler enjoys. Why use them?Ed Heal
Thanks for the advice @EdHeal, but that would not help in this case.Droopycom

1 Answers

2
votes

Read more about the C preprocessor. Read the documentation of GNU cpp. Notice its stringification and concatenation abilities.

Perhaps going thru some extra internal macro might help you, so you might have a public macro like

 #define FOO(X,Y,Z) PRIVATE_FOO(FOO,X,Y,Z)

with another PRIVATE_FOO macro doing stringification tricks on its first argument, maybe

#define PRIVATE_FOO(Mac,X,Y,Z) do { \
 printf("%s: %s,%s,%s\n", #Mac, #X, #Y, #Z); \
 Z = X+Y; Y=X; \
} while(0)

Perhaps the C preprocessor is not adequate for your task. You could generate some C code with some other tool (perhaps the GPP preprocessor, or perhaps a simple awk or python script, or perhaps some real program; you'll need to change your build process, e.g. your Makefile, to handle that). You could customize your GCC compiler with MELT if you need that. Since we don't know your actual motivations, we cannot help more.

I cannot help more, unless you motivate and clarify your question.

Your soft linking issue needs simply to use some weak symbols. It is probably unrelated to C preprocessing.