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

Ham*_*mza 2 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);

}
Run Code Online (Sandbox Code Playgroud)

该代码段的输出是:

param3: -1073748472
param3: 42
Run Code Online (Sandbox Code Playgroud)

对于第二个调用:'foo(1,1,42)',一切似乎都按预期工作.

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

我希望能够依赖于如果未调用参数,结果变量应该具有值0的事实.我原本以为va_arg()会足够明智地处理它,但似乎并非如此.

有什么建议可以处理吗?

非常感谢.

AnT*_*AnT 8

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

其次,试图"提取"一个不存在的可变参数会产生不确定的行为.因此,处理这个问题的唯一方法就是不要尝试提取不存在的参数.无法检测参数是否存在.调用者有责任通知函数可以安全地提取多少可变参数.


Jon*_*tte 7

问题在于,无论是否通过,您都在阅读该值.因此,你得到的任何垃圾碰巧都是在争论应该存在的偏移量的堆栈上.

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

更好的答案是"不要使用varargs;找到一些类型安全的方法来做你需要的东西."