局部(块)函数decln与defn返回类型不匹配; 在C++中进行诊断?

Don*_*wik 0 c c++ gcc

该程序位于名为localFunc.c的文件中:

#include <stdio.h>

// int f(int);  // Global forward declaration.

int main() {
   int f(int);  // Local forward declaration.
   printf("%d\n", f(1));
}

double f(int i) {
   return 1.0;
}
Run Code Online (Sandbox Code Playgroud)

编译via gcc localFunc.c给出:

localFunc.c:10:8: error: conflicting types for ‘f’
 double f(int i) {
        ^
localFunc.c:6:7: note: previous declaration of ‘f’ was here
    int f(int);  // Local forward declaration.
Run Code Online (Sandbox Code Playgroud)

但编译通过g++ localFunc.c,没有错误,运行可执行文件的结果是:4195638.

评论本地前向声明,并启用全局前向声明:int f(int);,gcc和g ++都会出现类似于上面的错误,正如预期的那样(由我).

所以我的问题是,为什么看起来g ++没有在本地声明的函数上看到冲突类型(模糊声明)?

don@HAL:~/UNIX/CS213$ gcc --version
gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010
Run Code Online (Sandbox Code Playgroud)

Nem*_*emo 5

我可以为C++解释这种行为.

从C++ 11规范,第3.5节[basic.link],第(7)节:

当找不到具有链接的实体的块范围声明来引用其他声明时,该实体是最内层封闭命名空间的成员.但是,此类声明不会在其命名空间范围中引入成员名称.

因此int f(int)声明具有全局链接,但不会将名称引入全局命名空间.这可以解释为什么GCC没有注意到冲突.

更重要的是,第(10)段说:

在对类型进行所有调整之后(其中typedefs(7.1.3)被其定义替换),引用给定变量或函数的所有声明指定的类型应该是相同的,除了数组对象的声明可以指定数组类型是否存在主阵列界限(8.3.4).违反此规则的类型标识不需要诊断.

您的程序违反了本段的"应"部分,因此其行为未定义.这意味着任何GCC都会做任何事情 - 例如调用double foo(int)函数并将其返回值视为int - 是规范允许的.而且,不需要诊断.

我不知道C对这个案子说了些什么; 特别是,是否需要诊断.