71

我有大约 30 个可变参数函数。每个都接受一个路径作为最后的参数,例如:

bool do_foo(struct *f, int q, const char *fmt, ...)

在每个函数中,我必须检查扩展格式是否小于或等于某个大小。所以,我发现自己复制/粘贴相同的代码块来检查有多少字符vsnprintf()没有打印,errno相应地设置并退出写入。

我想做的是编写一个函数来执行此操作,它将返回一个已知为安全大小的静态分配(扩展)字符串,或者在失败时返回新初始化的字符串,可以针对 NULL 进行检查。检查还必须确定字符串是绝对路径还是相对路径,这会影响字符串的安全大小。这是很多重复的代码,它开始闻起来了。

有没有办法可以将省略号的内容从我的函数条目传递给另一个函数?还是我必须先调用va_start(),然后将其传递va_list给辅助函数?

编辑:

我一点也不反对将它传递va_list给助手,我只是想确保没有其他东西存在。在我看来,编译器理解可变参数从哪里开始,所以我只是好奇我是否可以告诉它传递它们。

4

4 回答 4

71

你不能,你只能将参数作为va_list. 请参阅comp.lang.c 常见问题解答

一般来说,如果您在 C 中编写可变参数函数(即采用可变数量参数的函数),您应该为每个函数编写两个版本:一个采用省略号 ( ...),另一个采用va_list. 采用省略号的版本应该调用va_start,调用采用 a 的版本va_list,调用va_end,然后返回。函数的两个版本之间不需要重复代码,因为一个调用另一个。

于 2009-03-30T04:21:19.033 回答
12

可能您可以使用可变参数宏 - 像这样:

#define FOO(...)  do { do_some_checks; myfun(__VA_ARGS__); } while (0)

注意!可变参数宏仅适用于 C99

于 2009-03-30T06:00:03.540 回答
1

我不知道这是否有帮助,您可以通过引用访问变量。这是一种偷偷摸摸的技巧,但不幸的是,它不允许您在最终函数定义中使用省略号。

#include <stdio.h>

void print_vars(int *n)
{
  int i;
  for(i=0;i<=*n;i++)
    printf("%X %d  ", (int)(n+i), *(n+i));
  printf("\n");
}

void pass_vars(int n, ...)
{
  print_vars(&n);
}

int main()
{
    pass_vars(4, 6, 7, 8, 0);
    return 0;
}

在我的电脑上它输出

$ ./a.out
BFFEB0B0 4  BFFEB0B4 6  BFFEB0B8 7  BFFEB0BC 8  BFFEB0C0 0
于 2012-06-01T04:53:19.250 回答
0

您必须将 va_list 传递给助手。

于 2009-03-30T04:15:18.300 回答