【发布时间】:2020-02-25 09:24:24
【问题描述】:
我声明了一个具有以下签名的函数(实现被简化):
#include <stdio.h>
struct test_s{
int a, b;
};
void foo(struct test_s **out, size_t *szs, size_t arr_len){
for(size_t i = 0; i < arr_len; i++){
for(size_t j = 0; j < szs[i]; j++){
struct test_s ts = out[i][j];
printf("a = %d; b = %d\n", ts.a, ts.b);
}
}
}
如果调用者使用数组调整为指针,则可以如下调用:
int main(void){
struct test_s a1[] = {{0, 1}, {2, 3}, {4, 5}};
struct test_s a2[] = {{4, 6}};
foo((struct test_s *[]){a1, a2},
(size_t[]){sizeof a1 / sizeof(struct test_s), sizeof a2 / sizeof(struct test_s)},
2);
}
可以看出,函数调用看起来很复杂、容易出错且难以阅读。
当涉及到使用 3 个参数时,情况会变得更糟:
int main(void){
struct test_s a1[] = {{0, 1}, {2, 3}, {4, 5}};
struct test_s a2[] = {{4, 6}};
struct test_s a3[] = {{2, 3}, {4, 5}};
foo((struct test_s *[]){a1, a2, a3},
(size_t[]){sizeof a1 / sizeof(struct test_s), sizeof a2 / sizeof(struct test_s), sizeof a3 / sizeof(struct test_s)},
3);
}
因此,当涉及到数组时,最好将其实现为宏。实现它非常简单,如下所示:
#define FOO_ARR_2(a1, a2) \
do{ \
foo((struct test_s *[]){a1, a2}, \
(size_t[]){sizeof a1 / sizeof(struct test_s), sizeof a2 / sizeof(struct test_s)}, \
2);\
} while(0)
我发现这样的宏有 2 个问题:
- 我必须定义
FOO_ARR_3、FOO_ARR_4等... - 缺乏类型安全性。如果来电者传递了不同的东西,那么
struct test_s[]
问题:是否可以将其实现为像#define FOO_ARR(...) 这样的可变参数宏函数?
【问题讨论】:
-
"我声明了一个具有以下签名的函数" 您是完全使用此签名绑定到此,还是可以随意更改它?
-
@alk 是的,如果可以简化函数调用,可以更改签名
-
@alk 但我也需要支持
malloced 指针。这就是它被这样声明的原因
标签: c function macros type-safety variadic