簡體   English   中英

C中的變量函數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM