1

根据我对va_arg宏的了解,它检索参数列表指向的下一个参数。有什么方法可以选择我想要获取的参数的索引,比如数组索引?

例如,我需要执行一项操作,我需要调用至少 3 次va_arg宏,但我希望这 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]);
    } 

va_arg 为 SQLBindParameter 函数调用了 3 次,我希望前 2 次指向同一个参数,而不是增加参数列表中的 count 成员。

4

1 回答 1

1

First of all, calling va_arg multiple times in your function invocation is hairy, since you don't know in which order these calls happen. You need to do this beforehand, so your arguments are retrieved in the correct order.

Second, no: there is no array-style usage auf va_list. This is because va_list doesn't know a thing about the arguments on the stack; you are supplying the type in your va_arg calls, and va_arg can then increase the (internal/conceptual) pointer contained in the va_list because it knows the size of that argument. Getting to the third argument would require you to supply the types of the first two.

If all the arguments are the same size (like "void*") you can always just make a loop that calls va_arg the appropiate number of times. This is "kind of" portable if you can be reasonably sure that your arguments are in fact the same size. I'm not too confident that doing this would be the best course of action, though -- the need to do it might indicate that a different setup would be more appropiate, like passing an array in the first place instead of using a variable argument function.

You can also just take the address of a function argument and assume they are on the stack in some order. This is horribly unportable since you need to know about calling conventions which can vary between compilers, and may even change based on compilation options. I would definitely advise to NOT do something like this.

于 2012-07-28T10:01:39.627 回答