okay this sounds weird, the title is kinda confusing but heres what i mean basically :
#define make_name(id) cool_name_##id
#define my_cool_macro(id, type) void fun_##make_name(id)(type arg1)
my_cool_macro(hello, char);
this should expand to
/*
* passed through my_cool_macro
* vvvvv
*/
void fun_cool_name_hello(char arg1);
/* ~~~~^^^^^^^^^^^^^^^ */
~
--my_cool_macro
^
--make_name
i dont have a better way to explain this, any way to make this work ?
basically :
- define a function-like macro which can generate names
- define another function-like macro which calls to the defined name creating macro with an argument passed to the function creator macro
why am i doing this
im kinda trying to implement templaces in c using macros and as you know templated functions can have different types and i want to mangle the names but not repeat the cool_name_...
because what if i want to change the cool_name
to some_name
the solution should also work similarly to my example, so fun_##make_name(hello)
should work as should hello_##make_name(hello)
and ewuihewuifh_##make_name(hello)
without me needing to define a macro for every change
CodePudding user response:
You can do:
#include <stdio.h>
#define join(x, y) x##y
#define make_name_l(fn, id, arg_type) fn##id(arg_type)
#define make_name(fn, id, arg_type) make_name_l(fn, id, arg_type)
#define my_cool_macro(ret_type, id, arg_type) ret_type make_name(join (fun_, cool_name_), id, arg_type)
my_cool_macro(void, hello, char);
int main (void) {
fun_cool_name_hello('a');
return 0;
}
void fun_cool_name_hello (char a) {
printf ("In function : %s, arg : %c\n", __func__, a);
}
Additional:
In case, if you want to make it work with any type or number of arguments then you can use ellipsis (...
) and __VA_ARGS__
.
include <stdio.h>
#define join(x, y) x##y
#define make_name_l(fn, id, ...) fn##id(__VA_ARGS__)
#define make_name(fn, id, ...) make_name_l(fn, id, __VA_ARGS__)
#define my_cool_macro(ret_type, id, ...) ret_type make_name(join (fun_, cool_name_), id, __VA_ARGS__)
my_cool_macro(void, hello, char);
my_cool_macro(int, multiple_args, char, int, const char *);
my_cool_macro(void, no_args, void);
int main (void) {
const char * str = "test";
fun_cool_name_hello('a');
fun_cool_name_multiple_args('x', 5, str);
fun_cool_name_no_args();
return 0;
}
void fun_cool_name_hello (char a) {
printf ("In function : %s, arg : %c\n", __func__, a);
}
int fun_cool_name_multiple_args (char c, int i, const char * pstr) {
printf ("In function : %s, c : %c, i : %d, str : %s\n", __func__, c, i, pstr);
return i;
}
void fun_cool_name_no_args (void) {
printf ("In function : %s\n", __func__);
}
Output:
# ./a.out
In function : fun_cool_name_hello, arg : a
In function : fun_cool_name_multiple_args, c : x, i : 5, str : test
In function : fun_cool_name_no_args
https://godbolt.org/z/d67MWjasz
CodePudding user response:
You could have a macro that creates the prototype along with its type, as well as one that makes your custom name.
#define name(f) cool_name_##f
#define make_function(type, name, arg) type fun_name(arg)
#include <stdio.h>
#define name(f) cool_name_##f
#define make_function(type, name, arg) type fun_name(arg)
make_function(void, name(hello), int);
void cool_name_fun_hello(int f) {
printf("%d\n", f);
}
int main(void) {
cool_name_fun_hello(1);
}