根据我读到的关于va_arg
宏的内容,它会检索参数列表指向的下一个参数。有没有办法选择我想要获得的参数的索引,比如数组索引?
例如,我需要执行一个操作,我需要至少调用va_arg
宏的3倍,但我希望这3次检索相同的参数而不是列表中的下一个。一种解决方案可能是使用函数并传递参数,但我不希望这样。
此外,如果没有其他宏能够执行此操作,我如何通过指针引用数组参数的开头?我知道它不便携,不安全等等,只是为了学习。
以下是我想如何实现它的示例代码:
bool SQLBase::BindQuery (char* query, int NumArgs, ...)
{
va_list argList;
va_start(argList, NumArgs);
SQLPrepare (hstmt, query, SQL_NTS);
for (int x = 0; x < NumArgs; x++)
{
SQLBindParameter (hstmt, (x+1), GetTypeParameter (va_arg(argList, SQLPOINTER*), SQL_C_CHAR, SQL_CHAR, 10, 0, va_arg(argList, SQLPOINTER*), va_arg(argList, SQLLEN), &recvsize[x]);
}
对于SQLBindParameter函数,va_arg被调用3次,我希望前2次指向同一个参数,而不是增加参数列表上的count成员。
答案 0 :(得分:1)
首先,在函数调用中多次调用va_arg是多毛的,因为你不知道这些调用发生的顺序。您需要事先执行此操作,以便以正确的顺序检索您的参数。
第二,否:没有数组样式用法auf va_list。这是因为va_list不知道堆栈上的参数;你在va_arg调用中提供了类型,然后va_arg可以增加va_list中包含的(内部/概念)指针,因为它知道该参数的大小。获取第三个参数将要求您提供前两个类型。
如果所有参数都是相同的大小(如“void *”),你总是可以创建一个调用va_arg适当次数的循环。如果您可以合理地确定您的参数实际上是相同的大小,那么这种“便携式”是可移植的。我不太自信这样做是最好的行动方案,但是这样做的必要性可能表明不同的设置会更合适,比如首先传递数组而不是使用变量参数功能
您也可以获取函数参数的地址,并假设它们按某种顺序位于堆栈中。这非常难以置信,因为您需要了解调用约定,这些约定可能因编译器而异,甚至可能会根据编译选项进行更改。我肯定会建议不要做这样的事情。