2012-08-17 64 views
4

我有一個關於C99標準默認參數促銷的問題。在這本書中的 「C程序設計 - 一種現代方法,第二版」 我讀過:C99標準默認參數促銷

參數轉換:

[...]

1)編譯器有在通話之前遇到了原型。

2)編譯器在調用之前沒有遇到過原型。編譯器執行默認參數促銷:(1)float參數轉換爲double。 (2)執行積分促銷,導致參數charshort轉換爲int。 (在C99中,整數促銷被執行。

幾行進一步示出了其中不存在函數原型或定義調用前一個例子。它被評論如下:

當然,更好的解決方案是在調用它之前提供square的原型。 在C99中,在沒有首先提供函數的聲明或定義的情況下調用square是錯誤。

那兩個草書句是不是相互矛盾呢?我的意思是,如果C99禁止在沒有預先聲明/定義的情況下調用函數,它如何確定這種函數調用中的促銷?

回答

7

不,他們並不矛盾。

的聲明不一定是原型:

int f(); 

聲明函數f但不是原型,因爲沒有人知道有關參數類型。

int (a) 
in a; 
{ 
... 
} 

是一個定義,但不是原型。

+1

@JonathanLeffler,謝謝:) – 2012-08-17 15:58:42

2

C99不禁止您調用沒有原型的函數。

我不能給的細節,因爲你沒有張貼square()代碼或撥打,但據推測正在發生的事情是,在不同類型的調用的參數作出square()結果促進傳遞給該函數比它在實現中實際聲明的要多。

這就是什麼會導致未定義的行爲,並且會是一個錯誤。

例如:

// in foo.c: 

int foo(void) 
{ 
    char x = 42; 

    return square(x); // x is promoted to int, but is wrong 
} 


// in bar.c 

#include <stdio.h> 
void bar(int x) 
{ 
    square(&x); // this call is fine - what is being passed is what square() expects 
    printf("The result is %d\n", x); 
} 


// in square.c 

void square(int* p) 
{ 
    *p *= *p; 
    return; 
} 

如果square()與聲明的參數有char類型的參數原型定義,也沒有辦法正確地調用它沒有原型已經由「看到」在這種情況下,調用代碼將被提升爲int

1

我找不到任何關於它在調用函數時未提供C99中的預先聲明或定義的錯誤。

關閉的事情似乎是不再假定int的默認返回類型。即在C99之前允許聲明foo(int a);,但是在C99中有錯誤。前C99它意味着int foo(int a);