[英]Include First Argument in va_list object
是否可以在 va_list 中包含函數的第一個參數? 我想將參數從一個函數傳遞到另一個函數。
int main(){
test(1,2,3,4,5,-1);
}
void test(int firstArg, ...){
va_list va;
va_start(va, firstArg);
passFunction(va);
}
void passFunction(va_list va){
int x;
while((x = va_arg(ap,int))!=-1){
cout << x << endl;
}
}
我想要的輸出:
1
2
3
4
5
實際輸出:
2
3
4
5
有沒有辦法在不顯式將第一個參數傳遞給函數的情況下實現這一點?
我知道這是一個老問題,但我最近遇到了它,我想我會分享我的解決方案。 無論編譯器如何,此答案都應該有效,但會添加更多代碼。 我在 while 語句中使用第一個參數,但在使用第一個參數之前我不會調用 va_arg()。
main () {
test( 1, 2, 3, 4, 5, -1 );
}
void passFunction( int one, va_list va )
{
int x = one;
va_list va_copy;
va_copy( va_copy, va );
while (x != -1)
{
std::cout << x << std::endl;
x = va_arg( va_copy, int );
}
va_end( va_copy );
}
void test( int one, ... ) const
{
va_list va;
va_start(va,one);
passFunction( one, va );
va_end(va);
}
va_start()
需要一個固定參數,並將va_list
初始化為指定參數之后的下一個參數。 由於您的函數只有一個固定參數,因此無法選擇使用庫存va_start()
將其包含在va_list
中,因為它前面沒有固定參數。
僅在32位(64位更復雜)中,您可以將va_start()
編譯器源代碼從varargs.h
或stdargs.h
(或等效代碼) stdargs.h
到您自己的源文件中,然后進行調整以進行初始化帶有指定參數本身地址而不是va_arg
跟地址的va_arg
。
例如,在C ++ Builder中, va_start()
定義為:
#ifdef __cplusplus
#define va_start(ap, parmN) ((void)((ap) = (std::va_list)((char _FAR *)(&parmN)+__size(parmN))))
#else
#define va_start(ap, parmN) ((void)((ap) = (va_list)((char _FAR *)(&parmN)+__size(parmN))))
#endif
因此,您只需刪除+__size(parmN)
部分:
#ifdef __cplusplus
#define my_va_start(ap, parmN) ((void)((ap) = (std::va_list)((char _FAR *)(&parmN))))
#else
#define my_va_start(ap, parmN) ((void)((ap) = (va_list)((char _FAR *)(&parmN))))
#endif
在Visual Studio中, va_start()
定義為:
#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INSIZEOF(v) )
#define va_start _crt_va_start
因此,您只需刪除+ _INSIZEOF(v)
部分:
#define my_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) )
GCC實際上使用編譯器固有函數而不是宏,因此您可能無法獲取其va_start()
源,但是由於cdecl
調用約定(唯一支持32位可變參數的調用約定)已經標准化,因此生成的代碼應該相似跨編譯器。
無論哪種方式,預處理器生成的代碼最終都會大致相同,因此,如果與編譯器兼容,則可以直接對其進行編碼:
void test(int firstArg, ...){
va_list va = (va_list) &firstArg;
passFunction(va);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.