如何声明函数原型及其参数声明列表?

时间:2013-09-24 13:33:11

标签: c c99 function-declaration function-parameter

当我阅读ISO / IEC 9899:TC3 6.9.1 - >实施例13

并注意:

extern int max(int a, int b)
{
    return a > b ? a : b;
}

[...]

extern int max(a, b)
int a, b;
{
    return a > b ? a : b;
}
  

这里是int a,b;是参数的声明列表。这两个定义之间的区别是   第一个表单充当原型声明,强制转换后续调用的参数   到函数,而第二种形式没有。

所以我编写了自己的测试代码来编译它。 (我发现,两种方式都需要在之前声明,或者不得不使用所提到的类型定义的原型)

size_t foo (size_t a, size_t b);

int main(int argc, char** argv)
{
    /*some call to foo*/
    return 0;
}

所以我现在问:这种方式之间是否有任何与性能相关的差异:

size_t foo (a, b)
size_t a, b;
{   
    return a > b ? a : b;
}

和这一个?

size_t foo (size_t a, size_t b)
{   
    return a > b ? a : b;
}

因为据我所知,存在差异,因为第一种方式避免了函数调用时的多次转换,因为它表示不必转换为参数类型,因为它保证类型将是类型(在这种情况)size_t

但是我很困惑,因为我发现,原型在两种情况下都看起来相似,我认为原型是编译器接受治疗的来源。

那么:究竟是什么区别?如果有的话,为什么第一种方式很少(从未)见过?

3 个答案:

答案 0 :(得分:2)

这样做:

size_t foo (a, b)
size_t a, b;
{   
    return a > b ? a : b;
}

表示如果您现在这样称呼它:

int x = 3;
int y = 4;

foo(x,y);

在传递给函数之前,参数不会转换为size_t。这意味着您将获得未定义的行为(假设sizeof(size_t) > sizeof(int))。编译器不会警告你。这就是为什么在实践中没有人这样做的原因。

答案 1 :(得分:0)

第一种方式是旧的ISO标准。它在任何生产代码中都不再使用,但您仍可以在一些遗留代码中找到它。我怀疑除了语法之外,两者之间没有任何区别。

答案 2 :(得分:0)

此方法

size_t foo (a, b)
size_t a, b;
{   
    return a > b ? a : b;
}   

定义函数来自K& R C,所以你可能会在较旧的书籍和程序中遇到这种情况。 C89和C99支持这种风格。程序员出于几个原因避免在新程序中使用它。

首先,以旧方式定义的函数不会受到相同程度的错误检查。当以较旧的方式定义函数 - 且没有原型时 - 编译器不会检查函数是否使用正确数量的参数调用,也不会检查参数是否具有适当的类型。相反,它将执行默认参数提升

第二: 6.11.6函数声明符表示

  

使用带有空括号的函数声明符(不是prototype-format参数   类型声明者)是过时的功能