1

当我阅读 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.

但是我很困惑,因为我发现原型在两种情况下都必须看起来相似,我认为原型是编译器对其进行处理的来源。

那么:到底有什么区别?如果有,为什么第一种方式很少(从未)见过?

4

3 回答 3

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))。编译器不会警告你。这就是为什么没有人在实践中这样做。

于 2013-09-24T13:39:21.040 回答
0

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

于 2013-09-24T13:43:35.870 回答
0

这种方法

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

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

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

第二:6.11.6 函数声明器

使用带空括号的函数声明符(不是原型格式参数类型声明符)是一个过时的特性

于 2013-09-24T13:52:19.177 回答