45

在 C 或 C++ 中,函数声明和函数签名有什么区别?

我知道一些函数声明,但函数签名对我来说是全新的。有函数签名的概念有什么意义?这两个概念实际上是用来做什么的?

谢谢!

4

5 回答 5

52

函数声明是函数的原型(或者如果编译器当时没有看到原型,它可以来自函数定义) - 它包括返回类型、函数名称和参数类型(可选地在 C) 中。

函数签名是编译器用来执行重载解析的函数声明部分。由于多个函数可能具有相同的名称(即它们被重载),编译器需要一种方法来确定函数调用应解析为具有特定名称的几个可能函数中的哪一个。签名是编译器在重载决议中考虑的内容。具体来说,该标准将“签名”定义为:

有关参与重载决议的函数的信息:其参数的类型,如果函数是类成员,则函数本身的 cv 限定符(如果有)和声明成员函数的类。

请注意,返回类型不是函数签名的一部分。正如标准在脚注中所说,“函数签名不包括返回类型,因为它不参与重载决议”。

于 2010-02-24T01:09:28.627 回答
6

该标准定义了两个术语:声明和定义。定义是一个暂定的声明。但是,C99 和 C++03 标准的定义略有不同。

来自 C++0x 草案:

附录 C

8.3.5更改:在 C++ 中,使用空参数列表声明的函数不接受任何参数。在 C 中,空参数列表意味着函数参数的数量和类型未知”

定义

1.3.11 签名

函数的名称和参数类型列表 (8.3.5),以及它所属的类、概念、概念图或命名空间。如果函数或函数模板是类成员,则其签名还包括函数或函数模板本身的 cv 限定符(如果有)和 ref 限定符(如果有)。受约束成员 (9.2) 的签名包括其模板要求。函数模板的签名还包括其返回类型、模板参数列表和模板要求(如果有)。函数模板特化的签名包括它是其特化的模板的签名及其模板参数(无论是显式指定的还是推导出的)。[注意:签名用作名称修改和链接的基础。-结束注释]

于 2010-02-24T00:09:23.303 回答
4

函数签名不包括函数的返回类型或链接类型。

好的,维基百科不同意我对包含的返回类型的看法。但是我知道编译器在确定函数调用是否与签名匹配时不使用返回类型。这个以前的 StackOverflow 问题似乎同意:返回类型是函数签名的一部分吗?

于 2010-02-24T00:05:47.430 回答
2

另请注意,根据标准,顶级 const 和 volatile on 参数不是签名的一部分。但是有些编译器会出错。

例如

void f(const int, const char* const);

具有相同的签名

void f(int, const char*);
于 2010-03-08T16:26:34.857 回答
-1

函数声明是原型。函数签名指示返回类型是什么以及构成签名的参数。考虑一下:

int foo(int, int); /* 函数声明 */


/* foo 的实现
** 函数签名
*/
int foo(int a,int b){
}

现在,考虑这种情况:程序员被问到函数签名是什么foo

  • 它返回一个数据类型int
  • 两个参数的数据类型也分别为int、namedab

另一方面,函数原型是在 C/C++ 编译器中提示预期的内容,如果签名与原型不匹配,编译器将在“函数声明错误”的上下文中发出错误或“原型不匹配”。

于 2010-02-24T00:11:28.573 回答