【问题标题】:what is the difference between function declaration and signature?函数声明和签名有什么区别?
【发布时间】:2011-01-20 07:59:21
【问题描述】:

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

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

谢谢!

【问题讨论】:

  • 在形式上,C 中没有“函数签名”之类的东西。在 C 中根本不需要“函数签名”的概念。你的问题纯粹是C++。这在 C 中完全没有意义。
  • 那么在 C 中一个有意义的答案肯定是“无”,不是吗?

标签: c++ c function declaration signature


【解决方案1】:

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

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

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

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

【讨论】:

  • 说“函数声明是原型”并不完全正确。在 C++ 中它实际上是正确的,但在术语上是错误的,因为在 C++ 中没有“原型”这样的术语。在 C 中它是严格不正确的,因为在 C 中函数声明不一定是原型。例如,void foo(); 是一个函数声明,它没有在 C 中引入原型。实际上,这个问题不应该被标记为 C,因为 C 中没有“函数签名”的概念。它纯粹是一个 C++ 问题,并且,因此,答案不应提及任何“原型”。
  • 你能引用来源吗?
  • 您在没有明确区分的情况下引入了“签名”、“声明”、“原型”和“定义”。您可以编辑它以添加每个的具体示例吗?
【解决方案2】:

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

来自 C++0x 草案:

附录 C

8.3.5 更改:在 C++ 中,声明了一个函数 带有一个空参数列表不接受 论据。在 C 中,一个空参数 列表表示数量和类型 函数参数未知”

定义

1.3.11 签名

名称和参数类型列表 (8.3.5) 的函数,以及 类、概念、概念图或 它是其成员的命名空间。如果 函数或函数模板是 类成员其签名 还包括 cv 限定符(如果有)和 函数上的 ref 限定符(如果有) 或函数模板本身。这 受约束成员的签名 (9.2) 包括它的模板 要求。一个人的签名 额外的功能模板 包括它的返回类型,它的模板 参数列表及其模板 要求(如果有)。签名 函数模板特化 包括模板的签名 它是一个专业和 它的模板参数(无论是 明确指定或推断)。 [ 注:签名作为基础 用于名称修改和链接。—结束 注意]

【讨论】:

  • 谢谢,但我很难理解你想说什么。
  • 我知道函数声明,但函数签名对我来说是全新的。有函数签名的概念有什么意义?这两个概念实际上是用来做什么的?
  • @Tim: 1) C 标准没有定义术语签名。它在一般编程文献中被松散地使用,并且通常与函数声明同义。请注意,函数声明不需要有参数。但是,如果您在定义中使用定义,则可以。 2)签名被编译器广泛用于例如为标识符提供定义,如果是 C++,则选择最佳重载。
【解决方案3】:

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

好的,Wikipedia 不同意我对包含的返回类型的看法。但是我知道编译器在确定函数调用是否与签名匹配时不使用返回类型。这个以前的 StackOverflow 问题似乎同意:Is the return type part of the function signature?

【讨论】:

  • “存储类”是指函数所属的类吗?有函数签名的概念有什么意义?谢谢!
  • @Tim:不。他们指的是适用的链接。
  • 我现在不会太相信维基百科的文章。写的不太好。 方法签名文章好一点。
  • 我怀疑我混淆了我的术语 - 存储类是指变量,而不是函数。我的意思是静态或外部关键字所隐含的特征,例如。我已经更新了我的答案。
  • @Mark Ransom:staticextern 是存储类,可以应用于 C 和 C++ 中的函数。
【解决方案4】:

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

例如

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

有相同的签名
void f(int, const char*);

【讨论】:

    【解决方案5】:

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

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

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

    • 它返回int的数据类型
    • 两个参数也是int的数据类型,分别命名为ab

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

    【讨论】:

    • 谢谢!那么函数签名是函数定义中对应函数声明的部分吗?
    • @Tim:是的。确切地。 :) 希望这对你有意义?
    • 在 C 中,函数声明可能不是原型:int f(); 就是一个例子。
    猜你喜欢
    • 2013-05-21
    • 1970-01-01
    • 2013-10-19
    • 2014-06-26
    • 2010-11-27
    相关资源
    最近更新 更多