简体   繁体   English

在 c 宏中定义一个 function,其动态名称来自类似函数的 C 宏

[英]define a function in a c macro with a dynamic name coming from a function-like C macro

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 ~ -- my_cool_macro
  • ^ -- make_name ^ -- 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定义另一个类似函数的宏,它调用定义的名称创建宏,并将参数传递给 function 创建者宏

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我有点想在 c 中使用宏实现模板,正如你所知,模板函数可以有不同的类型,我想破坏名称但不重复cool_name_...因为如果我想将 cool_name 更改为cool_name 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该解决方案也应该与我的示例类似地工作,所以fun_##make_name(hello)应该像hello_##make_name(hello)ewuihewuifh_##make_name(hello)工作,而我不需要为每个更改定义宏

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__ .以防万一,如果你想让它与任何类型数量的 arguments 一起使用,那么你可以使用省略号 ( ... ) 和__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: 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 https://godbolt.org/z/d67MWjasz

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM