简体   繁体   English

为什么 function 原型在定义后更改是合法的?

[英]Why is it legal to change function prototype after its definition?

int test();
int test(){
 return 5;
}
int test(int in);

int main() {
   return test();
}

I know it's ok to have multiple (and similar) declarations of a function, and only 1 single definition.我知道可以有多个(和类似的)function 声明,并且只有 1 个单一定义。

My question is related to a declaration after its own definition.我的问题与自己定义后的声明有关。 Does the compiler pick the last prototype it has encountered as the true prototype?编译器是否选择它遇到的最后一个原型作为真正的原型? even if it comes father its full definition?即使它来自父亲的完整定义?

This doesn't compile with the error saying: error: too few arguments to function 'test'这不会编译并显示错误: error: too few arguments to function 'test'

There are three declarations of test in your sample code:您的示例代码中有三个test声明:

  1. int test(); is a declaration that is not a prototype 1 or a definition 2 .是不是原型1或定义2的声明。
  2. int test() { return 5; } int test() { return 5; } is a declaration that is a definition of the function. int test() { return 5; }是一个声明,它是 function 的定义。
  3. int test(int in); is a declaration that is a prototype for the function.是一个声明,它是 function 的原型。

The plain declaration, number 1, is incomplete.简单的声明,编号 1,是不完整的。 3 It leaves it unstated whether there are any parameters or what their types are. 3它没有说明是否有任何参数或其类型是什么。 This declaration can be completed by either declaration 2 or declaration 3, but not by both.此声明可以由声明 2 或声明 3 完成,但不能同时由两者完成。 If both 2 and 3 are present, a compiler should give you a warning or error message.如果 2 和 3 都存在,编译器应该给你一个警告或错误信息。 4 4

Specifically, to answer your question “Why is it legal to change function prototype after its definition?”: After an incomplete declaration, you can change what is known about the function type by adding more information, using either an old-style definition or a modern prototype.具体来说,要回答您的问题“为什么在定义后更改 function 原型是合法的?”:在声明不完整之后,您可以通过添加更多信息来更改关于 function 类型的已知信息,使用旧式定义或现代原型。 You cannot make changes other than adding more information.除了添加更多信息之外,您无法进行更改。 5 (After a prototype or a definition, the function type is complete, and you cannot make any changes.) 5 (原型或定义后,function型已完成,不能做任何改动。)

Declaration 2 matches an old style of function definition in which the parameters were defined after the closing ) and before the opening { :声明 2 匹配旧样式的 function 定义,其中参数在关闭之后定义)和打开之前{

return-type name-of-function(names-of-parameters)
declarations of parameters
{
    body-of-function
}

For example:例如:

int test(n, x)
int n;
double x;
{
    …
}

When there are no parameters in this style of definition, it means the function takes no parameters.这种定义中没有参数时,表示function不带参数。 Note the difference:注意区别:

  • int test(); does not say what the parameters are, not even how many there are.没有说参数是什么,甚至没有说有多少。
  • int test() { return 5; } int test() { return 5; } says there are no parameters. int test() { return 5; }说没有参数。

As you can see, these are compatible: Not stating how many parameters there are is compatible with saying there are no parameters.如您所见,这些是兼容的:不说明有多少参数与说没有参数是兼容的。 6 6

Declaration 3 is a modern declaration that says there is one parameter, with type int .声明 3 是一种现代声明,它说有一个参数,类型为int As with 2, declarations 1 and 3 are compatible: Not stating how many parameters there are or what types they might have is compatible with saying there is one parameter of type int .与 2 一样,声明 1 和 3 是兼容的:不说明有多少参数或它们可能具有哪些类型与说有一个int类型的参数是兼容的。

However, declarations 2 and 3 are incompatible:但是,声明 2 和 3 是不兼容的:

  • Declaration 2 says there are no parameters.声明 2 说没有参数。
  • Declaration 3 says there is one parameter.声明 3 说只有一个参数。

Footnotes脚注

1 A function prototype declares the types of its parameters. 1 function 原型声明了其参数的类型。 Since () is empty, there are no parameter types declared.由于()为空,因此没有声明参数类型。 (Due to C history, () in a function declaration means nothing is said about the parameters, and (void) is a prototype saying there are no parameters.) (由于 C 的历史,function 声明中的()表示没有提及参数,并且(void)是原型,表示没有参数。)

2 A function definition includes the body of the function, the brace-enclosed compound-statement containing the code the function executes. 2 function 定义包括 function 的主体,大括号括起来的复合语句包含 function 执行的代码。

3 “Incomplete” is used here in the ordinary English sense, not the sense in which the C standard applies to object types. 3这里使用的“不完整”是普通英语的意思,而不是 C 标准适用于 object 类型的意思。

4 This is required by the constraint in C 2018 6.7 4: “All declarations in the same scope that refer to the same object or function shall specify compatible types.” 4 This is required by the constraint in C 2018 6.7 4: “All declarations in the same scope that refer to the same object or function shall specify compatible types.”

5 There may be some minor changes possible. 5可能会有一些细微的变化。 For example, qualifiers such as const can be added to or removed from parameters, although this does not change the function type for purposes of compatibility.例如,可以在参数中添加或删除诸如const之类的限定符,尽管出于兼容性的目的,这不会更改 function 类型。

6 Specific rules for function type compatibility are in C 2018 6.7.6.3 15. 6 function类型兼容性的具体规则见C 2018 6.7.6.3 15。

This is an invalid code that does not satisfy the C Standard.这是不符合 C 标准的无效代码。

According to the C Standard (6.7.6.3 Function declarators (including prototypes))根据 C 标准(6.7.6.3 Function 声明符(包括原型))

  1. For two function types to be compatible... If one type has a parameter type list and the other type is specified by a function definition that contains a (possibly empty) identifier list, both shall agree in the number of parameters, and the type of each prototype parameter shall be compatible with the type that results from the application of the default argument promotions to the type of the corresponding identifier....对于要兼容的两个 function 类型...如果一个类型具有参数类型列表,而另一种类型由包含(可能为空)标识符列表的 function 定义指定,则两者应在参数数量和类型方面达成一致每个原型参数的类型应与将默认参数提升应用到相应标识符的类型所产生的类型兼容....

That is in the presented code there are declared two incompatible functions.也就是说,在呈现的代码中声明了两个不兼容的函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM