[英]Variadic functions in C
我有一個看起來像的功能
void demo_function_v(const char * mask, va_list ap)
{
for (; *mask; mask++) {
// get one or more args from ap, depending on *mask
}
}
這在AVR系統上運行,該系統具有不同的閃存訪問技術。 為了復制這個功能,我想提取它的主要部分:
void demo_function_1char(char mask, va_list ap)
{
// get one or more args from ap, depending on mask
}
void demo_function_v(const char * mask, va_list ap)
{
for (; *mask; mask++) {
demo_function_1char(*mask, ap)
}
}
唉,這不能保證工作,如
對象
ap
可以作為參數傳遞給另一個函數; 如果該函數使用參數ap
調用va_arg
宏,則調用函數中的ap
值是不確定的。
這是真的 - 在x86上,它不起作用,在x64上,確實如此。 如果它適用於AVR,我明天就能測試。 但如果被描述為“不確定”(據說是一種UB),我寧願不依賴於此。
因此,我想去另一條賽道:
void demo_function_1char(char mask, va_list * pap)
{
// get one or more args from *pap, depending on mask
}
void demo_function_v(const char * mask, va_list ap)
{
for (; *mask; mask++) {
demo_function_1char(*mask, &ap)
}
}
這應該是可行的,還是我會用這種方式射擊我的腳?
C99標准有以下腳注澄清:
允許創建指向va_list的指針並將該指針傳遞給另一個函數,在這種情況下,原始函數可以在另一個函數返回后進一步使用原始列表。
我相信這種行為也是C90的意圖,即使標准沒有注意到它。 C90理由文件確實有這樣的說法:
va_list
類型不一定是可分配的。 但是,函數可以將指針傳遞給其初始化的參數列表對象,如下所述。...
必須在要遍歷其參數列表的函數體內調用
va_start
。 然后,該函數可以將指向其va_list
對象ap
的指針傳遞給其他函數以進行實際遍歷。 (當然,它可以遍歷列表本身。)
我認為,非常明確地說,通過指針訪問va_list
對象的行為與您期望的一樣(即,在取自地址的對象實例中維護va_list
狀態),即使它沒有明確說明原始的va_list
對象將在指針用法停止的地方拾取。 因為它不能以這種方式工作,指向va_list
對象的指針必須與指向其他C對象的指針不同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.