C:使用stdarg.h的变量参数列表

时间:2010-06-05 00:06:24

标签: c variadic-functions

我正在尝试变量参数列表并看到一些奇怪的结果......

我正在测试的代码是:

#include <stdio.h>
#include <stdarg.h>

void foo(int param1, int param2, ...)
{
    int param3 = 0;

    va_list ap;
    va_start(ap, param2);
    param3 = va_arg(ap, int);
    va_end(ap);

    printf("param3: %d\n", param3);
}


int main(void)
{
  foo(1,1);
  foo(1,1,42);

}

该片段的输出是:

param3: -1073748472
param3: 42

对于第二个电话:'foo(1,1,42)',一切似乎都按预期工作。

对于第一个调用:'foo(1,1)',结果看起来像一个未初始化的int,虽然我在函数开始时首次初始化时将其设置为0。

如果不调用参数,我希望能够依赖结果变量的值为0的事实。我原以为va_arg()会足够明智地解决这个问题,但似乎并非如此。

有任何建议要处理吗?

非常感谢。

2 个答案:

答案 0 :(得分:8)

首先,我没有看到你将param3初始化为零的事实应该是重要的,因为无论如何你以后都会覆盖该值。

其次,尝试“提取”不存在的可变参数会产生未定义的行为。因此,处理它的唯一方法是 not 尝试提取不存在的参数。无法检测参数是否存在。调用者有责任通知函数可以安全地提取多少可变参数。

答案 1 :(得分:7)

问题在于,无论是否通过,您都在阅读该值。因此,你可以在争论应该存在的偏移量处得到堆栈中的任何垃圾。

使用varargs时,必须确保传递的初始参数清楚地表明存在其他参数。 printf()通过计算%符号来做到这一点(尽管程序员有时会出错,然后会出现欢闹)

更好的答案是“不要使用varargs;找到一些类型安全的方法来做你需要的。”