什么是C本地函数声明机制?

2023-12-06

gcc 中似乎允许本地函数声明,我发现了对此的讨论:局部函数声明有什么用处吗?

但是,我的问题是:ISO C 标准允许吗?如果是的话,如何解释以下令人费解的现象:

int main(void) {
    int f(void);
    f();
}
void g(void) {
    /* g has no idea about f. It seems that the decl is limited within its
     * scope */
    f(); 
}
int f(void) {}

while

int main(void) {
    int f(void);
    f();
}
void f(void); /* error because disagreement with the local declaration (local
             declaration goes beyound its scope?) */
void f(void) { /* definition here */ }

根据C99标准:函数名称属于同一命名类别。因此,我们将讨论范围机制来解释这一点。但如何呢?

实际上,我正在开发一个编译器课程项目,该项目要求我们实现一个简化版本的 C 编译器。我试图处理这个案子,但感到困惑。

EDIT:我知道众所周知,C 是面向过程的并且要求函数名称是唯一的。但这种地方性的声明方式搅动了清晰的局势,我很难理解其原则/规则。


ISO C 和 C++ 都允许本地函数声明。在每种情况下,函数声明的作用域都以局部作用域的末尾结束。然而,函数声明及其定义具有外部链接,因此它们仍然需要被链接器接受。

在您的样本中:

int main(void) {
 int f(void);
 f();
}
void f(void);
void f(void) {  }

这段代码无论是作为 C 代码还是 C++ 代码都可以正确编译。在 C 中应该链接(通常),但在 C++ 中则不会(因为“类型安全链接”)。将会有一个未解决的外部问题int f(void);.

[如果由于您的英语困难而无法回答您的问题,请澄清,我将编辑答案。]


C 标准包含以下内容。 n1570/S6.7.1/7:

具有块作用域的函数的标识符声明不得有显式的 除 extern 之外的存储类说明符。

显然,局部函数声明是明确允许的。


n1570 S6.2.2/5 外部连接:

如果函数标识符的声明没有存储类说明符,则其链接 的确定与使用存储类说明符 extern 声明时完全相同。如果 对象标识符的声明具有文件范围并且没有存储类说明符, 它的联系是外部的。

因此局部函数声明具有外部链接。这是显而易见的:如果它们有内部链接或没有链接,它们就无法链接到任何东西。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么是C本地函数声明机制? 的相关文章

随机推荐