簡體   English   中英

Variadic 函數最后一個參數類型

[英]Variadic function last parameter type

我在閱讀 C++ 標准時有這個問題,但它基本上只是引用 C 標准,所以我想這個問題適用於兩種語言。

來自[cstdarg.syn]

如果參數 parmN 是引用類型,或者是與傳遞沒有參數的參數時產生的類型不兼容的類型,則行為未定義。

我不明白關於“兼容”類型的規則。 兼容類型與 C 中的類型幾乎相同,那么這條規則究竟意味着什么? parmN不能是floatboolcharshort嗎?

int add_nums(short count, ...) 
{
    int result = 0;
    std::va_list args;
    va_start(args, count); // undefined behavior ?
    for (short i = 0; i < count; ++i) {
        result += va_arg(args, int);
    }
    va_end(args);
    return result;
}

另外,這條規則背后的原因是什么? 我知道parmN如何不能被引用,但我看不到它的類型與可變參數類型有何關系。

關於類型的規則與參數的提升有關。

對於可變參數,傳遞的類型為float的參數被提升為double ,類型小於int的整數參數被提升為intunsigned int 這意味着va_arg不能期望這些類型的參數,否則你會觸發未定義的行為

C11 標准的第 6.5.2.2p7 節中記錄了關於可變參數函數的這種行為:

如果表示被調用函數的表達式具有包含原型的類型,則參數將隱式轉換為相應參數的類型,就像通過賦值一樣,將每個參數的類型作為其聲明的非限定版本類型。 函數原型聲明符中的省略號會導致參數類型轉換在最后一個聲明的參數之后停止。 默認參數提升是在尾隨參數上執行的。

術語默認參數提升在 6.5.2.2p6 中定義:

如果表示被調用函數的表達式的類型不包含原型,則對每個參數執行整數提升,並將類型為float的參數提升為double 這些稱為默認參數提升

看一下:

在 C 參考中有一個很好的例子來說明(令人困惑的)語句的含義:

int add_nums(int count, ...);
int sum = add_nums(2, 'c', true); // add_nums is called with three ints: (2, 99, 1)

C++ 參考非常清楚地表明:

當調用可變參數函數時,在左值到右值、數組到指針和函數到指針的轉換之后,作為可變參數列表一部分的每個參數都會進行額外的轉換,稱為默認參數提升:

...

僅允許算術、枚舉、指針、指向成員的指針和類類型參數(轉換后)。 但是,...(其他一些東西)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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