2012-08-17 76 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);