這是一個奇怪的問題,但是在將它傳遞給另一個函數之前,是否有一種標準的方法來處理va_list
的內容?舉例來說,假設我有兩個功能,sum
和vsum
:操縱可變參數的標準方法?
int vsum(int n, va_list ap) {
int total = 0;
for (int i = 0; i < n; ++i) {
total += va_arg(n, int);
return total;
}
int sum(int n, ...) {
va_list ap;
va_start(ap, n);
int total = vsum(n, ap);
va_end(ap);
return total;
}
如果我打電話sum
爲sum(4, 1, 2, 3, 4)
,我希望得到的結果10.現在讓我們假設,而不是直接調用vsum
,sum
調用中間函數,vsum_stub
其執行以下操作:
int vsum_stub(int n, va_list ap) {
va_list temp_ap;
va_copy(temp_ap, ap);
for (int i = 0; i < n; ++i) {
int *arg = &va_arg(ap, int);
*arg += 2;
}
va_end(temp_ap);
return vsum(n, ap);
}
現在,當我打電話sum(4, 1, 2, 3, 4)
,我要取回結果20,因爲vsum_stub
增量的所有值在va_list
乘2.這當然不會編譯,因爲你不能把地址的結果作爲va_arg
。還有另一種方法可以做到這一點嗎?我在C99工作。
背景:
我的工作,做一些翻譯的指針,這樣的數據可以存儲在堆在一個更有效的格式庫。程序使用自定義轉換進行編譯,該轉換將調用轉換爲庫函數(如printf
),並將其轉換爲我自己的存根函數(例如,hc_printf
)。 hc_printf
需要在將參數傳遞給真實的printf
函數之前翻譯任何指針參數(用於%s
的字符串)。
編輯:下面是一個代碼示例。假設我們有一個字符串foo
。 foo
動態分配一個修改後的版本malloc
,它返回一個假指針。編譯器修改程序,以便它可以處理假指針。所以這個工程:
char *foo = fake_malloc(4);
fake_strcpy(foo, "foo");
我想寫一個fake_vprintf
函數這樣的(僞代碼):
int fake_vprintf(const char *format, va_list args) {
for each pointer argument p in args
translate p to q, a real pointer to contiguous memory
replace p with q in args
}
return vprintf(format, args);
}
該計劃將使用假指針調用fake_vprintf
就像當初vprintf
。 fake_vprintf
將假指針轉換爲實際vprintf
可以使用的實指針。
不應該'int * arg =&va_arg(ap,int);'實際上是'int * arg = va_arg(ap,int *);'? – dirkgently 2010-02-05 21:06:04
@dirkgently,不,參數列表中的實際參數是一個int。我在這個例子中的意圖是獲得一個指向該列表中的int的指針,以便我可以改變它的值。 – 2010-02-05 21:11:03
我假設'vsum_stub'接受了一個'int *'列表。無論如何,你認爲我發佈的代碼有什麼幫助嗎? – dirkgently 2010-02-05 21:14:51