该程序位于名为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)
我可以为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对这个案子说了些什么; 特别是,是否需要诊断.
| 归档时间: |
|
| 查看次数: |
86 次 |
| 最近记录: |