【问题标题】:Is `function-definition` a `declaration`?`function-definition` 是 `declaration` 吗?
【发布时间】:2021-01-31 03:56:07
【问题描述】:

在 C11 标准中

6.9 外部定义

语法

translation-unit:
external-declaration
translation-unit  external-declaration

external-declaration:
function-definition
declaration

在哪里

6.9.1 函数定义

语法

function-definition:
declaration-specifiers declarator  declaration-listopt compound-statement

declaration-list:
declaration
declaration-list  declaration

6.7 声明

语法

declaration:
declaration-specifiers init-declarator-listopt ;
static_assert-declaration

declaration-specifiers:
storage-class-specifier  declaration-specifiersopt
type-specifier  declaration-specifiersopt
type-qualifier  declaration-specifiersopt
function-specifier  declaration-specifiersopt
alignment-specifier  declaration-specifiersopt

init-declarator-list:
init-declarator
init-declarator-list , init-declarator

init-declarator:
declarator
declarator = initializer

...

声明指定了一组的解释和属性 标识符。标识符的定义是对该标识符的声明 标识:

  • 对于一个对象,导致为该对象保留存储空间;
  • 对于函数,包括函数体;
  • 对于枚举常量,是标识符的(唯一)声明;
  • 对于 typedef 名称,是标识符的第一个(或唯一一个)声明。

function-definitiondeclaration 吗?

declaration 是使用 function-specifier 还是 function-definition 或其他什么? (《6.7.4 函数说明符》引入了内联函数的定义,所以看起来function-definition就是declaration?)

external-declaration 中,为什么function-definition 被单独列出而不是包含在declaration 中?

谢谢。

【问题讨论】:

  • 函数定义也意味着声明(如果函数之前没有声明,那么定义也是声明)。

标签: c function declaration


【解决方案1】:

一个函数定义不是正式C语法中的一个声明。这从贯穿标准的语法条款中可以明显看出,它呈现了形式语法。

function-definition 是一个声明,它确实声明了函数的标识符,以及定义函数。这在 C 2018 6.9 5 中有说明,其中说“external definition 是一个外部声明,它也是函数(内联定义除外)或对象的定义……”

函数定义的语法需要与其他声明分开指定,因为它们的形式与其他声明不同。但是,正式语法中的标记可以被命名为 non-function-definition-declarationfunction-definition-declaration 而不是 declaration函数定义。名称对语法的定义没有影响,而 declaration 被选择作为实际上是声明子集的事实只是命名的产物。

【讨论】:

  • 谢谢。 declaration 是使用 function-specifier 还是 function-definition 或其他什么? 《6.7.4 函数说明符》介绍了内联函数的定义,所以看起来function-definition就是declaration
【解决方案2】:

标识符的定义是该标识符ref的声明

声明的概念与语法符号声明并不完全对应。 external-declaration(语法符号,斜体)不一定是declaration,但外部声明(罗马字体)显然是一种声明。我相信对该标准没有其他合理的解释。

语法是为机器(解析器)设计的,而英文文本是为人类设计的,所以这里和那里都有差异。

【讨论】:

  • 谢谢。 declaration 是使用 function-specifier 还是 function-definition 或其他什么? 《6.7.4 函数说明符》介绍了内联函数的定义,所以看起来function-definition就是declaration
【解决方案3】:

C 不允许在块内定义函数。所有函数定义都必须位于翻译单元的顶层。由于翻译单元的语法是一系列外部声明,因此我们只能在 external-declaration 的扩展中找到函数定义是合乎逻辑的。

当然,翻译单元的顶层并不局限于函数定义。它还可以包括声明,包括函数声明。但它不能包含(可执行)语句,在 C 语法的上下文中称为 statements

简而言之,C 语法包含三个相互排斥的类别,我们可以称之为“类似语句的事物”:

  • statement
  • declaration
  • function-definition

阻止列表包含前两个类别之一;翻译单元的顶层包含后两个中的任何一个。没有可以接受所有三个的上下文。

这些类别不是绝对的。另一种语言(或语法)可能使用不同的措辞。 (例如,在 C++ 中,声明就是语句,而函数定义可以出现在更多的上下文中。)

在普通语言中,将函数定义称为声明是很常见的。很明显,它声明了一个标识符来命名一个函数。在这个意义上,甚至标准偶尔也会使用“声明”。但它不在declaration的语法范畴内。

同样,声明不属于statement 的语法类别,尽管在非正式语言中,通常包含声明。 (不过,这是一个错误:声明不能被标记,甚至不能使用 case 标签。)

【讨论】:

  • 谢谢。 declaration 是使用 function-specifier 还是 function-definition 或其他什么? “6.7.4 函数说明符”引入了内联函数的定义,所以看起来function-definition就是declaration
  • function-definition 永远不是declarationfunction-specifier 可能出现在 function-definition 中,也可能出现在 declaration 中(前提是声明的标识符是 main (6.7.4/4) 以外的函数 (6.7.4/2)。所以function-specifier 不会改变语法类别。(你可以在没有函数体的情况下使用inline,只要在翻译单元的某处有函数的定义。)
  • @蒂姆:^^。另请注意,GCC 允许嵌套函数; GCC 扩展没有正式的语法,所以我不能说嵌套函数定义是否是 GCC 中的声明,或者他们是否认为函数定义是阻止列表项的另一种选择
  • 声明也不能是循环体。带有 RAII 的 C++ 会完全崩溃……
  • 在“6.7.4 函数说明符”中,所有示例都是带有inline__Noreturn 的函数定义,函数声明在哪里? 6.7.4 / 2 说“函数说明符只能在函数标识符的声明中使用。”,这是否意味着“函数说明符可能出现在函数定义中”?
猜你喜欢
  • 1970-01-01
  • 2012-05-22
  • 2022-07-14
  • 2016-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-18
  • 1970-01-01
相关资源
最近更新 更多