2010-05-31 84 views
3

我學到了----當默認的促銷活動中踢:使用默認參數提升究竟何時預期的參數類型是未知的,這是當有說沒有原型或者當爭論是可變的。參數提升的要求

但是一個例子困惑我的是:

void func(char a, char b) 
{ 
    printf("a=%p,b=%p\n",&a,&b);  
} 

int main(void) 
{ 
    char a=0x11,b=0x22; 

    func(a,b); 

    return 0; 
} 

它在上面的例子中cleard:調用主FUNC時,就沒有必要推進參數a和b,但輸出顯示&一= & b +4不是& a = & b + 1。如果沒有促銷發生,爲什麼兩個CHAR參數之間有4個字節?

+0

您可以提供第一段的來源嗎?它在哪裏說呢? – 2010-05-31 11:51:48

+0

C專家編程----彼得林登 P207第8章 其中隱式類型轉換髮生在參數passing.Under K&R C,因爲函數的參數是一個表達研究的另外的地方,類型提升發生在那裏。在ANSI C中,如果使用原型,參數不會被提升;否則,他們是。擴大的參數被裁減到它們在被調用函數中聲明的大小。 – HaoCheng 2010-05-31 12:08:21

回答

1

因爲編譯感覺就像在做這樣的說法:-)

無法推斷參數已經或尚未通過查看其地址剛剛晉升。 沒有要求參數在堆棧上傳遞(或者甚至它們完全通過堆棧)。

編譯器(和你的平臺調用約定)可能指定堆棧始終保持對齊4個字節,但是這是一個具體的實施細節,而不是C語言標準的一部分。

+0

這意味着它在上面的例子中根本沒有被提升? 你能告訴我,爲什麼一個lib功能,如 'ungetc函數' 聲明如下:ungetc函數INT(INT C,FILE *流)爲什麼不ungetc函數字符(字符C,FILE *流)?而幾乎每個FUNC傾向於使用INT而不是CHAR在他們的原型...... – HaoCheng 2010-05-31 12:20:13

+0

「ungetc函數」的返回值必須是INT,不CHAR,因爲它需要能夠返回EOF(這是該範圍以外的值CHAR)。類似地,'ungetc'的參數是INT,因爲允許傳遞EOF:「如果參數c字符的值等於EOF,則操作將失敗並且流將保持不變。」不過,更普遍的是,我懷疑許多標準庫函數採用INT的原因在於,它們可以追溯到K&R時期,因爲升級到INT是規則。請參閱http://stackoverflow.com/questions/1255775/default-argument-promotions-in-c-function-calls – 2010-05-31 15:09:34