代码之家  ›  专栏  ›  技术社区  ›  Edenia

GCC在应该决定函数声明的范围时的模糊行为

  •  0
  • Edenia  · 技术社区  · 2 年前

    通过阅读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开发人员中有文档记录。 link

    从外观上看,它确实会导致声明在文件范围内可见(不考虑标准C?),但在使用 -Werror=shadow ?它应该提示一个错误,即它隐藏了一个全局声明。 一劳永逸地说,编译器和链接器实际上是如何处理这些声明的,为什么?

    1 回复  |  直到 2 年前
        1
  •  1
  •   Chris Dodd    2 年前

    这里的问题是,有问题的函数声明具有块(函数)作用域,但也具有外部链接,冲突发生的地方就是外部链接。

    现在从规范来看,这样的链接冲突不需要引起诊断,但确实会导致未定义的行为,因此编译器将其标记为错误并不是错误的。