问题描述
考虑下面的C程序:
#include <stdio.h>
#include <stdarg.h>
typedef void (callptr)();
static void fixed(void *something, double val)
{
printf("%f\n", val);
}
static void dynamic(void *something, ...)
{
va_list args;
va_start(args, something);
double arg = va_arg(args, double);
printf("%f\n", arg);
}
int main()
{
double x = 1337.1337;
callptr *dynamic_func = (callptr *) &dynamic;
dynamic_func(NULL, x);
callptr *fixed_func = (callptr *) &fixed;
fixed_func(NULL, x);
printf("%f\n", x);
}
基本上,这个想法是存储与可变参数的函数在一个通用的函数指针。作为比较,我还包括固定的参数列表另一个函数。现在看到在x86的Linux,Linux的AMD64,Win32和Win64的运行此时会发生什么:
Basically, the idea is to store a function with variable arguments in a "generic" function pointer. As a comparison, I've also included another function with fixed argument list. Now see what happens when running this on x86 Linux, amd64 Linux, Win32 and Win64:
$ gcc -m32 -o test test.c
$ file test
test: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
$ ./test
1337.133700
1337.133700
1337.133700
$ gcc -o test test.c
$ file test
test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
$ ./test
1337.133700
1337.133700
1337.133700
C:\>gcc -o test.exe test.c
C:\>file test.exe
test.exe: PE32 executable for MS Windows (console) Intel 80386 32-bit
C:\>test.exe
1337.133700
1337.133700
1337.133700
C:\>x86_64-w64-mingw32-gcc -o test.exe test.c
C:\>file test.exe
test.exe: PE32+ executable for MS Windows (console) Mono/.Net assembly
C:\>test.exe
0.000000
1337.133700
1337.133700
为什么动态功能获得从Win64上可变参数列表零值,但不能在任何其它结构的?是这样的,即使合法的吗?我以为这是因为编译器并没有抱怨。
Why does the dynamic function get a zero value from the variable argument list on Win64, but not on any of the other configurations? Is something like this even legal? I assumed it is because the compiler didn't complain.
推荐答案
您code是无效的。调用可变参数函数需要一个原型,表明它的可变参数,而你使用的是不提供这个函数指针类型。为了使呼叫不未定义行为,你将不得不投了 dynamic_func
指针这样可拨打电话:
Your code is not valid. Calling a variadic function requires a prototype indicating that it's variadic, and the function pointer type you're using does not provide this. In order for the call not to invoke undefined behavior, you would have to cast the dynamic_func
pointer like this to make the call:
((void (*)(void *, ...))dynamic_func)(NULL, x);
这篇关于如何Win64上使用与函数指针可变参数一起使用C?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!