C 另一个函数中的函数声明有用吗?

C 另一个函数中的函数声明有用吗?,c,function,C,Function,我在读这篇文章,这篇文章与我的相关,尽管链接的问题是问为什么C语言中可以使用这种结构,但答案并没有说明这一点,也没有讨论其他一些问题。 我不明白在另一个函数中声明函数有什么好处,我甚至无法想象它真正有用的场景。 我想看一个例子,在这个例子中,内部声明可以带来外部无法带来的东西,或者至少是一个更好、更有用或更干净的场景。你说得对。在另一个函数中声明一个函数永远不会有用,因为函数总是在外部链接的,这与可能具有自动存储持续时间和块作用域的变量不同 由于可执行二进制文件的布局,一个函数总是可以从同一个二

我在读这篇文章,这篇文章与我的相关,尽管链接的问题是问为什么C语言中可以使用这种结构,但答案并没有说明这一点,也没有讨论其他一些问题。
我不明白在另一个函数中声明函数有什么好处,我甚至无法想象它真正有用的场景。

我想看一个例子,在这个例子中,内部声明可以带来外部无法带来的东西,或者至少是一个更好、更有用或更干净的场景。

你说得对。在另一个函数中声明一个函数永远不会有用,因为函数总是在外部链接的,这与可能具有自动存储持续时间和块作用域的变量不同

由于可执行二进制文件的布局,一个函数总是可以从同一个二进制文件中的另一个函数访问,因此在另一个函数中声明它是没有意义的,或者更准确地说,在有限范围内声明一个函数是没有意义的

我不明白拥有一个功能有什么好处 声明在另一个函数中,我甚至无法想象 这是一个非常有用的场景

该标准及其使用者(我们)有一个好处:该标准可以更简单地表达声明的语法和语义,而不会产生特殊的异常。关键不是在块范围内声明函数有什么特别的好处,而是这样做基本上是无害的,允许这样做会使语言更加一致

然而,在块范围内声明函数是一种糟糕的风格。这使得您的代码更难维护,因为如果函数签名发生更改,那么您需要查找并修复各地出现的问题。这就是为什么它几乎是无害的

对于您链接的问题,有一个答案认为块作用域函数声明有助于保持全局名称空间的整洁,但事实并非如此。尽管仅在块范围内声明函数并不意味着声明在该块外不可见,但在程序中的任何位置都不能有多个该函数的外部定义。对该名称的外部函数的所有引用都引用该函数,因此它在全局名称空间中占有一个位置,无论其标识符是否在任何特定转换单元的作用域中

我想看一个例子 内部声明可以带来外部无法带来的东西,或者 至少,这是一个更好、更有用或更干净的场景

没有这样的例子。在文件范围内声明函数总是更好、更干净的。此外,具有外部链接的函数应在头文件中声明,这些头文件
#将
d包含到引用或定义函数的翻译单元中

更新:
正如您在对这个答案的评论中所看到的,可以推测块作用域声明将允许从翻译单元调用外部函数,在翻译单元中声明相同的标识符,并带有内部链接,以引用其他内容。只有在标识符的任何文件范围声明之前的块内使用外部链接声明标识符,并且在以后的文件范围内使用内部链接声明标识符时,这种方案才能起作用。但这种情况是不允许的:在任何给定的整个翻译单元中,不能通过内部和外部链接声明相同的标识符。

您链接到的问题的答案之一声称它有用途,虽然我不相信。参见1)这不是标准C。2)与局部变量和全局变量-作用域限制相同。@JonnySchubert该问题涉及嵌套函数定义-这只涉及声明。@EugeneSh.,标准C不允许函数定义出现在块作用域,但它确实允许一个不是定义的函数声明出现在这样的范围内,它可能有些有用。例如,在Pascal中,嵌套函数可以访问包含函数的局部变量(有点像“局部-全局”变量)。我不确定gcc扩展是否也允许这样做。函数并不总是外部链接的。用
static
声明的函数具有内部链接(C 2011[N1570]6.2.2 3)。标准中防止
void foo(void){extern void xxx(void);}static int xxx?我在想,已经拥有名为
xxx
的内部函数或对象的人可能希望使用定义外部
xxx
的第三方代码,因此限制外部
xxx
的范围可以让他们这样做。然而,我的编译器对象(“重新定义……为不同类型的符号”),我在标准中看不到这样做的原因。我还不确定,@EricPostpischil。我仔细研究了一下,我的编译器甚至拒绝了当
xxx
在这两个地方被声明为函数时的场景,因为链接不同。但可能是编译器出错了。@EricPostpischil,看起来应该是:“如果在一个翻译单元中,同一个标识符同时出现在内部和外部链接中,则该行为是未定义的。”请注意,这里不需要重叠作用域。因此,您得到的错误消息有点误导,但行为尚未定义。