Car*_*rum 8 c gcc visual-studio-2003 variadic-functions
我有一个由一堆动态加载的模块组成的项目.最初,一切都是用MSVC 2003构建的,但最近我一直在努力让它与GCC一起工作.除了一个问题,一切都很顺利.对于64位代码,GCC和MSVC不同意它是什么va_list.对于32位,事情看起来很好.64位不匹配导致的问题是,使用一个编译器构建的模块具有带va_list参数的公共函数,并且该函数是从其他编译器构建的模块调用的.
除了第7.15节变量论证va_list之外,规范没有说明是什么,第3段:<stdarg.h>
声明的类型是
va_list其适合用于保持由宏所需信息的对象类型
va_start,va_arg,va_end,和va_copy.
那一段只是意味着这是所有编译器相关的东西 - 所以,有没有办法让这两个编译器就64位的内容达成一致va_list?对我的系统影响最小,使GCC与MSVC匹配va_list最好,但我会采取任何我能得到的解决方案.
谢谢你的帮助!
编辑:
我做了一些32位测试,我也有问题,这让我感到惊讶,因为任何32位Intel平台之间都没有ABI差异.我正在使用的MSVC代码库将所有可变参数函数宏定义为:
typedef char *va_list;
#define intsizeof(n) ((sizeof(n) + sizeof(int) - 1) &~(sizeof(int) - 1))
#define va_start(ap, v) (ap = (va_list)&(v) + intsizeof(v))
#define va_arg(ap, t) (*(t *) ((ap += intsizeof(t)) - intsizeof(t)))
#define va_end(ap) (ap = (va_list)0)
Run Code Online (Sandbox Code Playgroud)
我从实际项目中略微简化了一下,但这是我用于测试的代码.使用GCC,这段代码肯定没有正确得到我的论点.也许这只是一个bug,正如Zack在下面所说的那样?
再次编辑:
我得到的工作成果与下列32位测试应用程序-O0,-O0和-O2,但不-O3,-Os和-Oz:
typedef char *va_list;
#define intsizeof(n) ((sizeof(n) + sizeof(int) - 1) &~(sizeof(int) - 1))
#define va_start(ap, v) (ap = (va_list)&(v) + intsizeof(v))
#define va_arg(ap, t) (*(t *) ((ap += intsizeof(t)) - intsizeof(t)))
#define va_end(ap) (ap = (va_list)0)
int printf(const char *format, ...);
int f(int n, ...)
{
int r = 0;
va_list ap;
va_start(ap, n);
while (n--)
r = va_arg(ap, int);
va_end(ap);
return r;
}
int main(int argc, char **argv)
{
int r;
r = f(1, 1, 2, 3, 4, 5);
printf("%x\n", r);
r = f(2, 1, 2, 3, 4, 5);
printf("%x\n", r);
r = f(3, 1, 2, 3, 4, 5);
printf("%x\n", r);
r = f(4, 1, 2, 3, 4, 5);
printf("%x\n", r);
r = f(5, 1, 2, 3, 4, 5);
printf("%x\n", r);
return 0;
}
Run Code Online (Sandbox Code Playgroud)