C预处理器宏扩展连接
假设我想使用C预处理器来定义一个函数族,其中只有一个参数类型发生了变化。以带参数的分配函数为例:C预处理器宏扩展连接,c,macros,C,Macros,假设我想使用C预处理器来定义一个函数族,其中只有一个参数类型发生了变化。以带参数的分配函数为例: #include <stdint.h> #include <stdio.h> #define type_vector(t) \ t * t##vector(int32_t nl, int32_t nh) \ {
#include <stdint.h>
#include <stdio.h>
#define type_vector(t) \
t * t##vector(int32_t nl, int32_t nh) \
{ \
t * v = NULL; /* malloc(...) */ \
return v; \
}
type_vector(int8_t)
type_vector(int32_t)
type_vector(int64_t)
int main() {
int32_t * p;
p = int32_tvector(10, 12);
return 0;
}
但是,这不会编译,导致以下错误:
error: pasting ")" and "vector" does not give a valid preprocessing token
t * sn(t)##vector(int32_t nl, int32_t nh) \
据我所知,问题在于“)”和“#”并列。
因此,我做了以下工作:
#define sn_int8_t(f) i8##f
#define sn_int32_t(f) i32##f
#define sn_int64_t(f) i64##f
#define sn2(t,f) sn_##t(f)
#define type_vector(t) \
t * sn2(t,vector)(int32_t nl, int32_t nh) \
{ \
t * v = NULL; /* malloc(...) */ \
return v; \
}
type_vector(int8_t)
type_vector(int32_t)
type_vector(int64_t)
int main() {
int32_t * p;
p = i32vector(10, 12);
return 0;
}
这又起作用了
现在,假设我想在函数名中添加一个前缀,例如“remote\uux”
简单地说
#define type_vector(t) \
t * remote_##sn2(t,vector)(int32_t nl, int32_t nh) \
{ \
t * v = NULL; /* malloc(...) */ \
return v; \
}
不起作用,因为sn2没有扩展。所以我试了一下:
#include <stdint.h>
#include <stdio.h>
#define sn_int8_t(f) i8##f
#define sn_int32_t(f) i32##f
#define sn_int64_t(f) i64##f
#define sn2(t,f) sn_##t(f)
#define short_name(n,t,f) n##_##sn2(t,f)
#define remote_type_vector(t) \
t * short_name(remote,t,vector)(int32_t nl, int32_t nh) \
{ \
t * v = NULL; \
return v; \
}
remote_type_vector(int8_t)
remote_type_vector(int32_t)
remote_type_vector(int64_t)
int main() {
int32_t * p;
p = remote_i32vector(10, 12);
return 0;
}
有办法吗
<>注释:我不想使用C++模板。 这是一个统一的解决方案,应该满足所有的需要:
#define sn_int8_t(p,s) p##i8##s
#define sn_int32_t(p,s) p##i32##s
#define sn_int64_t(p,s) p##i64##s
#define sn2(t,p,s) sn_##t(p,s)
#define type_vector(t) \
t * sn2(t,,vector)(int32_t nl, int32_t nh) \
{ \
t * v = NULL; /* malloc(...) */ \
return v; \
}
#define remote_type_vector(t) \
t * sn2(t,remote,vector)(int32_t nl, int32_t nh) \
{ \
t * v = NULL; \
return v; \
}
type_vector(int8_t)
type_vector(int32_t)
type_vector(int64_t)
remote_type_vector(int8_t)
remote_type_vector(int32_t)
remote_type_vector(int64_t)
有些人声称这种魔法是邪恶的……使用灵活的数组成员会使思考变得简单得多。关于其余的:TL;DR.Provide a.“我不想在宏函数声明中添加第二个参数”-为什么不?并不是说你经常调用宏。第二个参数还允许您使用具有复合名称的类型(
char*
,struct thing
),而不使用typedef
。如果您不知道,可以使用gcc-E
检查预处理器的输出,我想所有C编译器都有这样做的选项。@EugeneSh。这样的黑魔法在史前时代就被禁止了。。至少在18世纪之前,巫术、巫术和巨魔术的实践者通常会被逐出教会或被绞死、抽签和分尸。
int32_t * remote_sn2(int32_t,vector)
#define sn_int8_t(p,s) p##i8##s
#define sn_int32_t(p,s) p##i32##s
#define sn_int64_t(p,s) p##i64##s
#define sn2(t,p,s) sn_##t(p,s)
#define type_vector(t) \
t * sn2(t,,vector)(int32_t nl, int32_t nh) \
{ \
t * v = NULL; /* malloc(...) */ \
return v; \
}
#define remote_type_vector(t) \
t * sn2(t,remote,vector)(int32_t nl, int32_t nh) \
{ \
t * v = NULL; \
return v; \
}
type_vector(int8_t)
type_vector(int32_t)
type_vector(int64_t)
remote_type_vector(int8_t)
remote_type_vector(int32_t)
remote_type_vector(int64_t)