C Preprocessor to split "int x" into int & x

I need to get the following:

#define MY_MACRO(PARAM1,PARAM2) \ MY_OTHER_MACRO(TYPENAME_OF(PARAM1),PARAMNAME_OF(PARAM1));\ MY_OTHER_MACRO(TYPENAME_OF(PARAM2),PARAMNAME_OF(PARAM2));\ 

cause

 MY_MACRO(int x,char *z) 

to compile as

 MY_OTHER_MACRO(int,x); MY_OTHER_MACRO(char*,z); 

or it’s not the end of the world if it is compiled as:

 MY_OTHER_MACRO(int,x); MY_OTHER_MACRO(char,*z); 

or even this will also be fine: (I can program MY_OTHER_MACRO to work with any result)

 MY_OTHER_MACRO(int,x); MY_OTHER_MACRO(char,z); 

alternatively, if there is some way of counting tokens separated by spaces (and suppose that "*" is a separate token, I can also work with this - for example, 2 vs. 3) as a rule, tokens are separated by commas, as far as I know. is there any way to use another character?

+2
source share
2 answers

You can do this, but only with an extremely difficult restriction that you must know all type names in advance: it will not work with any custom types unless the user adds them to the list of known types too - admittedly, this is not difficult.

Accepting this restriction, you can do something like this:

 #define LPAREN ( #define RPAREN ) #define COMMA , #define CAT(L, R) CAT_(L, R) #define CAT_(L, R) L ## R #define EXPAND(...) __VA_ARGS__ #define SPLIT(OP, D) EXPAND(OP CAT(SPLIT_, D) RPAREN) #define SPLIT_int LPAREN int COMMA #define SPLIT_char LPAREN char COMMA #define SPLIT_float LPAREN float COMMA #define SPLIT_double LPAREN double COMMA #define MY_MACRO(A, B) \ SPLIT(MY_OTHER_MACRO, A); SPLIT(MY_OTHER_MACRO, B); MY_MACRO(int x, char * z) // emits MY_OTHER_MACRO ( int , x ); MY_OTHER_MACRO ( char , * z ); 

Adding a type to the list of known types is, as mentioned above, single-line ( #define SPLIT_myType LPAREN myType COMMA ) and can be executed anywhere in the program until it is used before the type is actually used by SPLIT , so this is not the end of light, although he is very intrusive.

There is no easy way to get an asterisk to the left of the split. This could probably be done, but it would have been much more complicated and would have required a restriction on the list of allowed variable names, which IMO is much, much worse. Probably more intrusive, as you almost certainly have more variables than types in your work program.

+8
source

It's impossible.

One alternative may be to have different parameters for the type and indexer.

 MY_MACRO(int, x, char *, z) 
0
source

Source: https://habr.com/ru/post/1269219/


All Articles