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-definition
是declaration
吗?
declaration
是使用 function-specifier
function-definition
还是其他什么? (“6.7.4函数说明符”引入了内联函数的定义,所以看起来function-definition
是declaration
?)
在
external-declaration
中,为什么单独列出function-definition
而不是包含在declaration
中?
函数定义不是正式 C 语法中的声明。这从整个标准中呈现形式语法的语法子句中可以明显看出。
A function-definition 是一个声明,它确实声明了函数的标识符,并定义了函数。 C 2018 6.9 5 中对此进行了说明,其中表示“外部定义是外部声明,也是函数的定义(内联定义除外)或对象......”
函数定义的语法需要与其他声明分开指定,因为它们的形式与其他声明不同。然而,形式语法中的标记可以被命名为 non-function-definition-declaration 和 function-definition-declaration,而不是 declaration 和 function-definition。这些名称对语法的定义没有影响,而选择“声明”来表示实际上是声明的子集的事实只是命名的产物。
external-declaration
的扩展中找到函数定义,这是合乎逻辑的。
当然,翻译单元的顶层并不局限于函数定义。它还可以包含声明,包括函数声明。但它不能包含(可执行)语句,这些语句在 C 语法的上下文中称为statements
。
简而言之,C 语法包含三个互斥的类别,我们可以将其称为“类似语句的事物”:
statement
declaration
function-definition
这些类别并不是绝对的。另一种语言(或语法)可能使用不同的措辞。 (例如,在 C++ 中,声明是语句,函数定义可以出现在更多上下文中。)
在普通语言中,很常见的说法是函数定义是声明。显然,它声明了一个标识符命名了一个函数。即使标准偶尔也使用这种意义上的“声明”。但它不属于
declaration
的语法范畴。
同样,声明也不属于statement
的语法范畴,尽管在非正式语言中,通常包含声明。 (不过,这是一个错误:声明不能被标记,即使带有 case 标签也是如此。)