使用 C 预处理器生成多个相似函数
Generate multiple similar functions with C preprocessor
我想生成多个相似的函数来替换整个函数中的一个词。
例如,对于以下各项:
OBJECT = customer
OBJECT = account
使用函数模板:
void add_OBJECT_to_array(void* item_ptr, int pos)
{
mtx_lock(&OBJECT_array_mtx);
OBJECT_array[pos] = *(OBJECT_t*)item_ptr;
mtx_unlock(&OBJECT_array_mtx);
return;
}
这样我就可以打电话
add_order_to_array(ord, 1);
add_customer_to_array(cust, 1);
这可能吗?
完全有可能。您只需要了解预处理器连接运算符 ##
。以下代码将生成两个函数 add_order_to_array
和 add_customer_to_array
.
#define GENERATE_FUNC(OBJECT) \
void add_ ## OBJECT ## _to_array(void* item_ptr, int pos)\
{ \
mtx_lock(&OBJECT ## _array_mtx); \
OBJECT ## _array[pos] = *(OBJECT ## _t*)item_ptr; \
mtx_unlock(&OBJECT ## _array_mtx); \
return; \
}
GENERATE_FUNC(order)
GENERATE_FUNC(customer)
预处理器输出将是(不幸的是它不考虑格式):
void add_order_to_array(void* item_ptr, int pos) { mtx_lock(&order_array_mtx); order_array[pos] = *(order_t*)item_ptr; mtx_unlock(&order_array_mtx); return; }
void add_customer_to_array(void* item_ptr, int pos) { mtx_lock(&customer_array_mtx); customer_array[pos] = *(customer_t*)item_ptr; mtx_unlock(&customer_array_mtx); return; }
是的,这是可能的:
#define DECLARE_ADD_FUNCTION(__obj) \
void add_##__obj##_to_array(void* item_ptr, int pos) \
{ \
mtx_lock(&__obj##_array_mtx); \
__obj##_array[pos] = *(__obj##_t*)item_ptr; \
mtx_unlock(&__obj##_array_mtx); \
return; \
}
DECLARE_ADD_FUNCTION(customer)
DECLARE_ADD_FUNCTION(account)
当您查看预处理器的输出时,您会得到:
gcc -E foo.c
void add_customer_to_array(void* item_ptr, int pos) { mtx_lock(&customer_array_mtx); customer_array[pos] = *(customer_t*)item_ptr; mtx_unlock(&customer_array_mtx); return; }
void add_account_to_array(void* item_ptr, int pos) { mtx_lock(&account_array_mtx); account_array[pos] = *(account_t*)item_ptr; mtx_unlock(&account_array_mtx); return; }
您甚至可以通过将函数原型更改为 add_##__obj##_to_array(__obj##_t *, int pos)
来确保指针类型是正确的类型
我想生成多个相似的函数来替换整个函数中的一个词。
例如,对于以下各项:
OBJECT = customer
OBJECT = account
使用函数模板:
void add_OBJECT_to_array(void* item_ptr, int pos)
{
mtx_lock(&OBJECT_array_mtx);
OBJECT_array[pos] = *(OBJECT_t*)item_ptr;
mtx_unlock(&OBJECT_array_mtx);
return;
}
这样我就可以打电话
add_order_to_array(ord, 1);
add_customer_to_array(cust, 1);
这可能吗?
完全有可能。您只需要了解预处理器连接运算符 ##
。以下代码将生成两个函数 add_order_to_array
和 add_customer_to_array
.
#define GENERATE_FUNC(OBJECT) \
void add_ ## OBJECT ## _to_array(void* item_ptr, int pos)\
{ \
mtx_lock(&OBJECT ## _array_mtx); \
OBJECT ## _array[pos] = *(OBJECT ## _t*)item_ptr; \
mtx_unlock(&OBJECT ## _array_mtx); \
return; \
}
GENERATE_FUNC(order)
GENERATE_FUNC(customer)
预处理器输出将是(不幸的是它不考虑格式):
void add_order_to_array(void* item_ptr, int pos) { mtx_lock(&order_array_mtx); order_array[pos] = *(order_t*)item_ptr; mtx_unlock(&order_array_mtx); return; }
void add_customer_to_array(void* item_ptr, int pos) { mtx_lock(&customer_array_mtx); customer_array[pos] = *(customer_t*)item_ptr; mtx_unlock(&customer_array_mtx); return; }
是的,这是可能的:
#define DECLARE_ADD_FUNCTION(__obj) \
void add_##__obj##_to_array(void* item_ptr, int pos) \
{ \
mtx_lock(&__obj##_array_mtx); \
__obj##_array[pos] = *(__obj##_t*)item_ptr; \
mtx_unlock(&__obj##_array_mtx); \
return; \
}
DECLARE_ADD_FUNCTION(customer)
DECLARE_ADD_FUNCTION(account)
当您查看预处理器的输出时,您会得到:
gcc -E foo.c
void add_customer_to_array(void* item_ptr, int pos) { mtx_lock(&customer_array_mtx); customer_array[pos] = *(customer_t*)item_ptr; mtx_unlock(&customer_array_mtx); return; }
void add_account_to_array(void* item_ptr, int pos) { mtx_lock(&account_array_mtx); account_array[pos] = *(account_t*)item_ptr; mtx_unlock(&account_array_mtx); return; }
您甚至可以通过将函数原型更改为 add_##__obj##_to_array(__obj##_t *, int pos)