Pass several arguments as macro in C - c

Sorry for bad English.
Suppose the code:
#define FOO(x,y) FOO ## x
#define BAR A, B
FOO(A, B) successfully expanded to FOOA. But when I write FOO(BAR), the C preprocessor (gcc -E) give error
error: macro "FOO" requires 2 arguments, but only 1 given
How I should change FOO macro if I want expand FOO(BAR) to FOOA?

#define FOO(X, Y) FOO ## X
#define BAR A, B
#define APPLY(F, X) F(X)
APPLY(FOO, BAR)
or
#define FOO(X) FOO_(X)
#define FOO_(X, Y) FOO ## X
#define BAR A, B
FOO(BAR)

Related

C Preprocessor: concatenate macro call with token

I'm trying to concatenate a macro call with a token to create a new one, for instance:
#define TEST(X) X ## _TEST
#define CONCAT(X) TEST(X) ## _CONCAT
CONCAT(OK);
Then I check the output with gcc -E; I would want to get OK_TEST_CONCAT; but instead I get an error:
error: pasting ")" and "_CONCAT" does not give a valid preprocessing token
If I remove ## I get no error but the output is OK_TEST _CONCAT;
This is a minimal example, so the easiest here would be to combine everything in a single macro, but know that it's impossible for me to get rid of the first call to TEST. Is there a way to remove that space?
Thanks
EDIT:
Ok so from the confusion maybe my example was a little too minimal, that's my fault. Here is a more plausible use case:
I want all the prototypes in a certain header to be prefixed by the PREFIX defined in that header.
proto.h:
#define EXPAND(X) EXPAND_HELPER(X)
#define EXPAND_HELPER(X) X
#define PROTO(NAME) PREFIX ## NAME
other.h:
#include <proto.h>
#define PREFIX other
int PROTO(test)(int a, int b);
...
What I want is all the prototypes in other.h to have this form: int other_test(int a, int b);. But as it is they have this form: int PREFIX_test(int a, int b);. After googling I found that I needed to force PREFIX to rescan, so I tried this:
#define PROTO(NAME) EXPAND(PREFIX) ## NAME
which prompted my question. Now if I look at #Lundin's answer, I can adapt it to give what I want:
Solution:
#define PROTO(NAME) PROTO_HELPER(PREFIX, NAME)
#define PROTO_HELPER(PREFIX, NAME) PROTO_EXPAND(PREFIX, NAME)
#define PROTO_EXPAND(PREFIX, NAME) PREFIX ## NAME
Thanks!
All preprocessor tokens must be expanded before a function-like macro using ## or # is called. Because ## or # is applied before macro expansion. In your case TEST(X) only expands X into TEST(OK) and then the preprocessor attempts to paste TEST(OK) with _CONCAT which won't work. For each attempt to concatenate tokens, you must first expand all macros before ##, which is done by extra helper macros that force a rescanning/replacement.
The contrived solution given #define TEST(X) X ## _TEST would be this:
#define CONCAT(X) EXPAND_HELPER(TEST(X)) // expands TEST(X) to TEST(OK)
-->
#define EXPAND_HELPER(X) CONCAT_HELPER(X, _CONCAT) // expands TEST(OK) to OK_TEST
-->
#define CONCAT_HELPER(X,Y) X ## Y
That is:
// NOTE: contrived solution, avoid
#define TEST(X) X ## _TEST
#define CONCAT_HELPER(X,Y) X ## Y
#define EXPAND_HELPER(X) CONCAT_HELPER(X, _CONCAT)
#define CONCAT(X) EXPAND_HELPER(TEST(X))
...
int CONCAT(OK) = 1; // becomes int OK_TEST_CONCAT = 1;
A much simpler solution would be:
#define CONCAT(X) X ## _TEST ## _CONCAT

How to concatenate with ## an item from a tuple without using a GLUE macro in the C preprocessor?

I have a big code base that looks like this:
#define LIB_TUP_0_(A, B, C) A
#define LIB_TUP_0(TUP) LIB_TUP_0_ TUP
#define LIB_TUP_1_(A, B, C) B
#define LIB_TUP_1(TUP) LIB_TUP_1_ TUP
#define LIB_TUP_2_(A, B, C) C
#define LIB_TUP_2(TUP) LIB_TUP_2_ TUP
#define LIB_PARAM_PFX LIB_TUP_0
#define LIB_PARAM_T LIB_TUP_1
#define LIB_PARAM_NAME LIB_TUP_2
#define F(PARAM) \
F_(LIB_PARAM_PFX(PARAM), LIB_PARAM_T(PARAM))
#define FS(PARAM) \
FS_(LIB_PARAM_T(PARAM), LIB_PARAM_PFX(PARAM), LIB_PARAM_NAME(PARAM))
#define F_(PFX, T) \
T PFX##_hello(T a);
#define FS_(T, PFX, NAME) \
T PFX##_hello(T NAME) { return NAME; }
with a header definition F and a source definition FS for a lot of things.
The problem is that PARAM is a (new) standard way to provide parameters to the entire library and it needs to be a tuple of the form (PFX, T, NAME). Some macros though only require certain parameters from this tuple or need to be passed in a different order.
The problem is that a lot of code doesn't use the 'glue' macro and I thought if there is a way to not have to use it...
This is an undesired, but working example:
#define LIB_GLUE(a, b) a##b
#define LIB_TUP_0_(A, B, C) A
#define LIB_TUP_0(TUP) LIB_TUP_0_ TUP
#define LIB_TUP_1_(A, B, C) B
#define LIB_TUP_1(TUP) LIB_TUP_1_ TUP
#define LIB_TUP_2_(A, B, C) C
#define LIB_TUP_2(TUP) LIB_TUP_2_ TUP
#define LIB_PARAM_PFX LIB_TUP_0
#define LIB_PARAM_T LIB_TUP_1
#define LIB_PARAM_NAME LIB_TUP_2
#define F(PARAM) \
F_(LIB_PARAM_PFX(PARAM), LIB_PARAM_T(PARAM))
#define FS(PARAM) \
FS_(LIB_PARAM_T(PARAM), LIB_PARAM_PFX(PARAM), LIB_PARAM_NAME(PARAM))
#define F_(PFX, T) \
T LIB_GLUE(PFX, _hello)(T a);
#define FS_(T, PFX, NAME) \
T LIB_GLUE(PFX, _hello)(T NAME) { return NAME; }
#define M (l, int, b)
F((l, int, ))
FS(M)
Undesired because I can't (maybe) afford to change every PFX##_hello to LIB_GLUE(PFX, _hello) in the entire code base. So I'm here asking if there is any way out of this without having massive refactoring issues.

C Macros: How to map another macro to variadic arguments?

I'd like to know how to apply a unary function (or another macro) to variadic arguments of a macro, like
int f(int a);
#define apply(args...) <the magic>
apply(a, b, c)
which unrolls
f(a)
f(b)
f(c)
Note that the number of arguments is unknown.
The code below is working for what you've asked for with up to 1024 arguments and without using additional stuff like boost. It defines an EVAL(...) and also a MAP(m, first, ...) macro to do recursion and to use for each iteration the macro m with the next parameter first.
With the use of that, your apply(...) looks like: #define apply(...) EVAL(MAP(apply_, __VA_ARGS__)).
It is mostly copied from C Pre-Processor Magic. It is also great explained there. You can also download these helper macros like EVAL(...) at this git repository, there are also a lot of explanation in the actual code. It is variadic so it takes the number of arguments you want.
But I changed the FIRST and the SECOND macro as it uses a Gnu extension like it is in the source I've copied it from. This is said in the comments below by #HWalters:
Specifically, 6.10.3p4: "Otherwise [the identifier-list ends in a ...] there shall be more arguments in the invocation than there are parameters in the macro definition (excluding the ...)".
Main function part:
int main()
{
int a, b, c;
apply(a, b, c) /* Expands to: f(a); f(b); f(c); */
return 0;
}
Macro definitions:
#define FIRST_(a, ...) a
#define SECOND_(a, b, ...) b
#define FIRST(...) FIRST_(__VA_ARGS__,)
#define SECOND(...) SECOND_(__VA_ARGS__,)
#define EMPTY()
#define EVAL(...) EVAL1024(__VA_ARGS__)
#define EVAL1024(...) EVAL512(EVAL512(__VA_ARGS__))
#define EVAL512(...) EVAL256(EVAL256(__VA_ARGS__))
#define EVAL256(...) EVAL128(EVAL128(__VA_ARGS__))
#define EVAL128(...) EVAL64(EVAL64(__VA_ARGS__))
#define EVAL64(...) EVAL32(EVAL32(__VA_ARGS__))
#define EVAL32(...) EVAL16(EVAL16(__VA_ARGS__))
#define EVAL16(...) EVAL8(EVAL8(__VA_ARGS__))
#define EVAL8(...) EVAL4(EVAL4(__VA_ARGS__))
#define EVAL4(...) EVAL2(EVAL2(__VA_ARGS__))
#define EVAL2(...) EVAL1(EVAL1(__VA_ARGS__))
#define EVAL1(...) __VA_ARGS__
#define DEFER1(m) m EMPTY()
#define DEFER2(m) m EMPTY EMPTY()()
#define IS_PROBE(...) SECOND(__VA_ARGS__, 0)
#define PROBE() ~, 1
#define CAT(a,b) a ## b
#define NOT(x) IS_PROBE(CAT(_NOT_, x))
#define _NOT_0 PROBE()
#define BOOL(x) NOT(NOT(x))
#define IF_ELSE(condition) _IF_ELSE(BOOL(condition))
#define _IF_ELSE(condition) CAT(_IF_, condition)
#define _IF_1(...) __VA_ARGS__ _IF_1_ELSE
#define _IF_0(...) _IF_0_ELSE
#define _IF_1_ELSE(...)
#define _IF_0_ELSE(...) __VA_ARGS__
#define HAS_ARGS(...) BOOL(FIRST(_END_OF_ARGUMENTS_ __VA_ARGS__)())
#define _END_OF_ARGUMENTS_() 0
#define MAP(m, first, ...) \
m(first) \
IF_ELSE(HAS_ARGS(__VA_ARGS__))( \
DEFER2(_MAP)()(m, __VA_ARGS__) \
)( \
/* Do nothing, just terminate */ \
)
#define _MAP() MAP
#define apply_(x) f(x);
#define apply(...) EVAL(MAP(apply_, __VA_ARGS__))
To test macro expansion it is useful to use gcc with the command line argument -E:
$ gcc -E srcFile.c
because your're getting concrete error messages and understand what's going on.
Everything is possible in C if you throw enough ugly macros at it. For example, you can have an ugly function-like macro:
#include <stdio.h>
int f (int a)
{
printf("%d\n", a);
}
#define SIZEOF(arr) (sizeof(arr) / sizeof(*arr))
#define apply(...) \
{ \
int arr[] = {__VA_ARGS__}; \
for(size_t i=0; i<SIZEOF(arr); i++) \
{ \
f(arr[i]); \
} \
}
int main (void)
{
apply(1, 2, 3);
}
Notice that 1) This would be much better off as a variadic function, and 2) it would be even better if you get rid of the variadic nonsense entirely and simply make a function such as
int f (size_t n, int array[n])

C Macro building with defines

I am having trouble getting this macro expanison right
#define foo Hello
#ifdef foo
#define wrapper(x) foo ## x
#else
#define wrapper(x) boo ## x
#endif
calling:
wrapper(_world)
I would like the result of
Hello_world
however, the macro is treating the "foo" define as a literal, and thus giving
foo_world
Can someone point out my mistake?
Thanks
I would recommend gnu-cpp-manual which clearly explains how macros are expanded.
Macro arguments are completely macro-expanded before they are substituted into a macro body, unless they(macro arguments) are stringified or pasted with other tokens (by the macro function that is directly applied to).
For example:
If an argument is stringified or concatenated, the prescan does not occur.
#define AFTERX(x) X_ ## x
#define XAFTERX(x) AFTERX(x)
#define TABLESIZE 1024
#define BUFSIZE TABLESIZE
AFTERX(BUFSIZE) => X_BUFSIZE: since AFTERX is to concatenate argument with prefix, its argument is not expanded, remaining BUFSIZE.
XAFTERX(BUFSIZE) => X_1024: XAFTERX does not do concatenation directly, so BUFSIZE will be expanded first.
Generally, arguments are scanned twice to expand macro called in them.
--- edit ---
So the better practice is: (code from QEMU source)
#ifndef glue
#define xglue(x, y) x ## y
#define glue(x, y) xglue(x, y)
#define stringify(s) tostring(s)
#define tostring(s) #s
#endif
glue(x,y) will concatenate x and y with both already expanded.

Two identical preprocessor definitions give different results

Consider the snippet:
#define CAT(a, b) a##b
#define M_0 CAT(x, y)
#define M(a) CAT(M_, a)()
M(0);
#define N_0() CAT(x, y)
#define N(a) CAT(N_, a)()
N(0);
To me both definitions of M(a) and N(a) look identical.
However, cpp of GCC 4.6.1 expands this to:
CAT(x, y)();
xy;
Why?
#define M_0 CAT(x, y)
#define N_0() CAT(x, y)
M_0 is a simple text replacement. N_0 is a macro function that, when being evaluated, evaluates any other macro functions as necessary.

Resources