【发布时间】:2011-11-08 07:49:56
【问题描述】:
问题'Pass va_list or pointer to va_list?' 的答案引用了标准(ISO/IEC 9899:1999 - §7.15 'Variable arguments <stdarg.h>, footnote 212)明确表示:
允许创建指向
va_list的指针并将该指针传递给另一个函数,在这种情况下,原始函数可以在其他函数返回后进一步使用原始列表。
我正在编译一些代码,可以通过以下示例来说明(实际代码要复杂得多,原始函数比这里显示的要多得多)。
vap.c
#include <stdarg.h>
#include <stdio.h>
static void test_ptr(const char *fmt, va_list *argp)
{
int x;
x = va_arg(*argp, int);
printf(fmt, x);
}
static void test_val(const char *fmt, va_list args)
{
test_ptr(fmt, &args);
}
static void test(const char *fmt, ...)
{
va_list args;
va_start(args, fmt); /* First use */
test_val(fmt, args);
va_end(args);
va_start(args, fmt); /* Second use */
test_ptr(fmt, &args);
va_end(args);
}
int main(void)
{
test("%d", 3);
return 0;
}
错误信息
当我编译它时(在带有 GCC 4.1.2 或 4.5.1 的 RHEL5 上),我收到以下错误消息。请注意 4.5.1 错误消息提供了多少信息 - GCC 团队的改进值得祝贺!
$ gcc --version
gcc (GCC) 4.5.1
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ /usr/bin/gcc --version
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gcc -c vap.c
vap.c: In function ‘test_val’:
vap.c:13:5: warning: passing argument 2 of ‘test_ptr’ from incompatible pointer type
vap.c:4:13: note: expected ‘struct __va_list_tag (*)[1]’ but argument is of type ‘struct __va_list_tag **’
$ /usr/bin/gcc -c vap.c
vap.c: In function ‘test_val’:
vap.c:13: warning: passing argument 2 of ‘test_ptr’ from incompatible pointer type
$
我在使用 GCC/LLVM 4.2.1 和 GCC 4.6.1 的 MacOS X Lion 上收到相同的消息:
$ /usr/bin/gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gcc --version
gcc (GCC) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$
问题
-
有人能解释为什么
test_val()函数不能将va_list作为参数传递给test_ptr(),而test()函数(它创建了va_list)可以吗? GCC 抱怨
test_val()中指针的间接传递是否正确?
在这两种情况下,我都可以模糊地看到答案,但我无法简洁地描述它。我认为test_val() 中的代码滥用了va_list,代码无法编译很好——但我想在修复它之前确定一下。
2012-03-30 更新
这周我去处理有问题的代码。在进行更改之前,我去查找了错误函数的使用位置——它们不是!因此,我通过删除函数(4 个外部可见但未使用的函数,加上 2 个包含有问题代码的静态函数)解决了我的编译错误问题。这比必须弄清楚如何处理混乱要简单得多。 (这也解释了为什么从来没有任何证据表明代码会导致运行时问题。)
【问题讨论】:
标签: c variadic-functions