2010-07-30 96 views
17

假設我有一個函數,它從另一個這樣的函數傳遞可變參數(...)或va_list。主要邏輯是在這個函數本身(我們稱之爲f1),但我想讓它通過va_list到另一個函數(我們稱之爲f2),它將確定下一個參數類型,使用va_arg獲得它,並正確地轉換和存儲它供呼叫者使用。將va_list或指針傳遞給va_list?

將va_list傳遞給f2是否足夠,或者是否需要將指針傳遞給va_list。除非va_list被要求是一個數組類型,否則將其位置數據存儲在對象指向的位置(而不是對象本身),我看不到如何通過值傳遞它可以允許調用函數(f1)以'看'va_arg所做的被調用函數的變化。

任何人都可以闡明這一點嗎?我對該標準要求的內容感興趣,而不是某些特定實現允許的內容。

回答

23

看起來您需要將指針傳遞給va_list。有關詳細信息,請參閱C99 standard document部7.15.In特別地,項目符號點3種狀態:

對象AP可以作爲參數傳遞給 另一個函數被傳遞;如果該函數調用與參數AP的va_arg宏中在調用函數AP的 值是不確定的,並應被傳遞到va_end用來 宏之前的任何進一步參照AP

[我的斜體]

編輯:只注意到在標準腳註:

215)它被允許創建一個指針的va_list和指針傳遞給另一個函數,在這種情況下, 原有的功能可以在其他功能後要進一步利用原有列表返回

所以你可以傳遞一個指向va_list的和被調用函數做va_arg(*va_list_pointer)

+0

同意你最後一次編輯 - 指針是要走的路(因爲OP希望對'va_list'的更改在調用函數中明確可見)。 – caf 2010-07-30 08:48:19

+0

@caf:我不認爲你應該編輯出我對'vfprintf()'的引用,因爲它看起來像別人正在犯同樣的錯誤,並建議提問者看看現有的原型(實際上並沒有回答他的問題)。 – JeremyP 2010-07-30 09:18:59

+2

我會說留下評論和/或投票他們然後 - 它似乎更好有正確的答案不混淆與更早的,不正確的假設... – caf 2010-07-30 12:05:33

2

在我的理解中,你應該直接傳遞va_list(而不是指向它的指針)。這似乎是comp.lang.c支持:

「的va_list本身不是一個變量參數列表,它真的排序的指針,一個是,它接受的va_list功能本身並不是可變參數,也沒有副反之亦然「。

+0

我不認爲這句話支持你的論點。沒有什麼關於它不允許將指針傳遞給'va_list',並且實際上標準明確地說這是允許的。 – caf 2010-07-30 12:08:10

2

我覺得這個問題的文字很模糊。最簡單的方法可能是查看標準va_list應該接收的預定義函數,例如vsnprintf。這顯然是有價值的,而不是參考。在標準C庫通va_list元件本身

+1

標準函數不打算被調用的方式OP想要 - 在被調用之後,'va_list'不能再使用,只能傳遞給'va_end()'。 – caf 2010-07-30 12:07:11

+0

事實上,我是OP,我同意caf在這一個。 JeremyP是唯一一個似乎引用了任何證據的人,標準很清楚你必須爲我想要的語義傳遞一個指針。 – 2010-07-30 12:28:12

0

功能(man 3 vprintf):

#include <stdarg.h> 

    int vprintf(const char *format, va_list ap); 
    int vfprintf(FILE *stream, const char *format, va_list ap); 
    int vsprintf(char *str, const char *format, va_list ap); 
    int vsnprintf(char *str, size_t size, const char *format, va_list ap); 
+1

這些函數都不打算以OP的方式調用 - 在調用這些函數後,'va_list'不能再使用,只能傳遞給'va_end()'。 – caf 2010-07-30 12:06:55

0

指針傳遞到va_list的在32位的系統正常工作。您甚至可以在子例程中一次讀取一個參數。 但它似乎在64位系統中不起作用,會在va_arg()處產生段錯誤。