通过阅读 C99 标准规范草案 (n1256) 第 6.7.5.3 节第 17 段,我可以得出块作用域内的函数声明(包括隐式声明)应具有块作用域。简单又有意义。
但是它没有任何意义,因为当我编译这段代码时:
void func1 () {
int f(int);
}
void func2 () {
float f(float);
}
int main (void) {
return 0;
}
编译器产生错误:
错误:‘f’的类型冲突;有“浮动(浮动)”
就好像它在文件范围内看到了两个声明。另一个类似的情况是,如果我用函数调用替换函数声明,而没有首先为其提供可见声明,以强制隐式声明。 (是的,我知道这是一个过时的功能)。发生的情况是,隐式函数声明警告仅发出一次,因此促使我相信它也在文件范围内以某种方式神奇地声明了。我唯一合理的解释是一些 GCC 扩展,我确实找到了类似的东西,但它记录在 ARM 开发人员中。 链接
从表面上看,它确实导致声明在文件范围内可见(不考虑标准 C?),但是在使用
-Werror=shadow
编译时,它到底为什么以及如何例外呢?它应该提示一个错误,因为它隐藏了全局声明。
一劳永逸地,编译器和链接器实际上如何处理这些声明,为什么?
这里的问题是,所讨论的函数声明具有块(函数)作用域,但也具有外部链接,而正是外部链接发生了冲突。
现在从规范来看,像这样的链接冲突不需要导致诊断,但确实会导致未定义的行为,因此编译器将其标记为错误并不是不正确的。