为什么 C 中的嵌套函数违反 C 标准

Why nested functions in C are against C standards

C 标准(ANSI[C89]、C99、C11)不允许嵌套函数(块作用域中的函数声明)。

但我找不到 C 标准中的说明。

编辑:

为什么函数定义不能在函数定义(复合语句)中?

嵌套或私有函数是许多 C 编译器过去允许的,但不是 C 标准的一部分,现在很少能找到支持它们的编译器,当然是默认情况下。

标准由委员会确定,嵌套函数将是他们讨论过的东西,并且会有理由,但我不知道它是什么,大多数C程序员也不知道。嵌套函数本质上并不是一个坏主意,但您可以通过编写静态文件作用域函数来实现几乎所有的好处,这是创建标准化私有函数的方法。

函数声明和函数定义之间存在差异。声明仅声明函数的存在,而定义则定义函数。

int f(void) { /* ... */ } // function definition
int f(void);              // function declaration

在 6.9.1 中,函数的语法定义为

函数定义: declaration-specifiers declarator declaration-listopt compound-statment

在 6.8.2 中,可以放在复合语句中的内容被定义为 声明 语句 。函数定义在语法上不被认为是这些中的任何一个。

所以是的,函数声明在函数中是合法的,但函数定义不是例如

int main(int argc, char*argv[])
{
    int f(void);                // legal
    int g(void) { return 1; } ; // ILLEGAL

    // blah blah
}

它可能不会直接说明,但如果你研究函数定义的语法,你会发现它们在语法中不被接受。

为什么?根据 Dennis Richie(在这方面有点权威)的说法,他们似乎从一开始就被排除在外:

"Procedures can be nested in BCPL, but may not refer to non-static objects defined in containing procedures. B and C avoid this restriction by imposing a more severe one: no nested procedures at all."

https://www.bell-labs.com/usr/dmr/www/chist.html

通过施加更严格的限制来避免限制是一种幽默。我读这个是因为它是一种简化的操作。嵌套过程增加了编译器的复杂性(Ritchie 非常热衷于限制当时的机器)并且几乎没有增加价值。

标准化过程(明智地)从未被视为随意扩展 C 的机会,并且(来自同一文档):

"From the beginning, the X3J11 committee took a cautious, conservative view of language extensions."

很难证明嵌套函数提供了显着的好处,因此即使某些实现支持它们也没有被采纳为标准也就不足为奇了。

总的来说,从那以后的标准工作至少同样保守,而且很难看到实施者中有很多支持添加这样的功能。

归根结底,如果您担心某些功能会在其预期目的之外使用并且(逻辑上)恰好是一个给定功能的子功能,那么请为其提供静态链接并引入另一个源文件或甚至整个翻译单元。