Variadic 函数在 Win32 中有效,但在 Win64 中无效
Variadic function works in Win32 but not in Win64
我使用以下功能已经有一段时间了:
void AddRow(int iNumOfColumns,...)
{
int* pValuePerColumn = (int*)&iNumOfColumns+1;
for (int i=0; i<iNumOfColumns; i++)
{
// Do something with pValuePerColumn[i]
}
}
现在我们的一位客户发现它在 Win64 上崩溃了。
我手边没有 64 位平台,但我假设原因是:
调用函数时,参数将作为 64 位值压入堆栈。
在这种假设下,我认为将 int*
替换为 size_t*
应该可以解决问题。
我的问题是:
- 我的分析是否正确?
- 我的解决方案正确吗?
- 有没有更"conventional"的方法来解决这个问题?
取消引用指向数组最后一个元素或非数组对象的指针是未定义的行为:
int* pValuePerColumn = (int*)&iNumOfColumns+1;
...
pValuePerColumn[i]
将类型更改为 size_t
与此问题无关。
使用可变参数的唯一正确方法是 stdarg.h 中提供的宏。
您应该使用 varargs
以可移植的方式访问额外的参数。查找 va_list
文档。可能你的代码应该看下一个
void AddRow(int iNumOfColumns,...)
{
va_list ap;
va_start(ap, iNumOfColumns);
for (int i=0; i<iNumOfColumns; i++)
{
int col = va_arg(ap, int);
// Do something with col
}
va_end(ap);
}
我记得在 Win64 上,前四个整数参数是通过寄存器传递的,而不是通过堆栈传递的,所以使用指针的技巧是行不通的。
我使用以下功能已经有一段时间了:
void AddRow(int iNumOfColumns,...)
{
int* pValuePerColumn = (int*)&iNumOfColumns+1;
for (int i=0; i<iNumOfColumns; i++)
{
// Do something with pValuePerColumn[i]
}
}
现在我们的一位客户发现它在 Win64 上崩溃了。
我手边没有 64 位平台,但我假设原因是:
调用函数时,参数将作为 64 位值压入堆栈。
在这种假设下,我认为将 int*
替换为 size_t*
应该可以解决问题。
我的问题是:
- 我的分析是否正确?
- 我的解决方案正确吗?
- 有没有更"conventional"的方法来解决这个问题?
取消引用指向数组最后一个元素或非数组对象的指针是未定义的行为:
int* pValuePerColumn = (int*)&iNumOfColumns+1;
...
pValuePerColumn[i]
将类型更改为 size_t
与此问题无关。
使用可变参数的唯一正确方法是 stdarg.h 中提供的宏。
您应该使用 varargs
以可移植的方式访问额外的参数。查找 va_list
文档。可能你的代码应该看下一个
void AddRow(int iNumOfColumns,...)
{
va_list ap;
va_start(ap, iNumOfColumns);
for (int i=0; i<iNumOfColumns; i++)
{
int col = va_arg(ap, int);
// Do something with col
}
va_end(ap);
}
我记得在 Win64 上,前四个整数参数是通过寄存器传递的,而不是通过堆栈传递的,所以使用指针的技巧是行不通的。