Reputation: 47
Suppose I would like to use the C Preprocessor to define a family of function, for which only a parameter type changes. Let's take for example allocation functions with parameters:
#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;
}
This works fine.
Now, suppose I would like to have shorter names for type in the function names: i8 instead of int8_t, i32 instead of int32_t, etc. I do not want to add a second parameter to the macro function declaration, but instead have a single definition of "short" type names. Basically, the first thing I wrote was:
#define sn_int8_t i8
#define sn_int32_t i32
#define sn_int64_t i64
#define sn(t) sn_##t
#define type_vector(t) \
t * sn(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;
}
However, this does not compile, giving the following error:
error: pasting ")" and "vector" does not give a valid preprocessing token
t * sn(t)##vector(int32_t nl, int32_t nh) \
As far as I understood, the problem is due to having the ")" and the "#" side by side. So I did the following:
#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;
}
And this works fine again.
Now, suppose I would like to add a prefix to the function name, e.g. "remote_".
Simply putting
#define type_vector(t) \
t * remote_##sn2(t,vector)(int32_t nl, int32_t nh) \
{ \
t * v = NULL; /* malloc(...) */ \
return v; \
}
does not work, as sn2 is not expanded. So I tried this:
#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;
}
Basically, this does not work because the macro sn2 is not expanded, giving me declarations like:
int32_t * remote_sn2(int32_t,vector)
Is there any way to do that?
Note: I do not want to use C++ templates.
Upvotes: 2
Views: 208
Reputation: 24102
Here's a unified solution that should work for all of your needs:
#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)
Upvotes: 0