Consider the following C program:
#include <stdio.h>
#include <stdarg.h>
typedef void callptr();
static void fixed(void *something, double val)
{
printf("%f
", val);
}
static void dynamic(void *something, ...)
{
va_list args;
va_start(args, something);
double arg = va_arg(args, double);
printf("%f
", 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
", x);
}
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
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.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…