Variadic函数在Win32中有效,但在Win64中无效

时间:2016-07-21 08:26:13

标签: c 64-bit variadic-functions

我已经使用了以下功能很长一段时间了:

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*可以解决问题。

我的问题是:

  • 我的分析是否正确?
  • 我的解决方案是否正确?
  • 是否有更“传统”的解决方法?

2 个答案:

答案 0 :(得分:5)

在指向数组的最后一个元素或非数组对象之后,将指针解析为一个未定义的行为:

int* pValuePerColumn = (int*)&iNumOfColumns+1;
...
pValuePerColumn[i]

将类型更改为size_t与此问题无关。

使用变量参数的唯一正确方法是stdarg.h中提供的宏。

答案 1 :(得分:3)

您应该使用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上,前四个整数args通过寄存器传递,而不是通过堆栈传递,因此使用指针的技巧将无效。