当外部变量在其他文件中声明不同时,如何使G 产生警告

How to make g++ generate warning when extern variable declared differently in other file?

本文关键字:何使 警告 变量 外部 其他 文件 声明      更新时间:2023-10-16

我有两个文件:

A.CPP

#include <iostream>
using namespace std;
int a[100];
int main() {
  cout << "Hello World" << endl;
}

B.CPP

#include <iostream>
using namespace std;
extern double a[50];

显然,两个文件中有" A"的冲突声明。但是当我运行

g++ a.cpp b.cpp

汇编默默成功。

有什么办法可以使G 抱怨冲突(通过警告或错误)?

我尝试了-wshadow和-wshadow -all标志。他们没有帮助。

检测到这一点的一种方法是将extern声明始终放入标题(.h)文件中,并将此文件包括在定义这些变量的源模块中。

如果创建一个" A.H"文件,则可以将其包含在" A.CPP"answers" B.CPP"中。随后的编译将导致错误,因为类型在标题中的extern double a[50];声明与" A.CPP"中的int a[50];定义之间不匹配。

使用GCC的最新版本,您可以将-flto标志使用到编译器和链接器。这会调用链接时间优化,在某些情况下确实会捕获extern变量之间的类型不匹配。

您还可以通过确保在标题文件中声明任何外部链接的名称来帮助避免此问题。如果extern double a[50];出现在a.cppb.cpp包含的通用标题中,您将获得a.cpp的汇编错误。

请注意,这不是"阴影",这就是为什么影子标志没有帮助的原因。阴影是当您在内部范围内重复使用相同名称的时候,该名称已经存在于外部范围中的名称,例如void f() { int x; { double x; } }。但是,两个不同的翻译单元不是重叠的范围。

从g "观点"观点"没有冲突。可变double a[50]在B.CPP文件中受到约束。由于a存在于A.CPP中,因此您使用同一变量的错误感知。在B.CPP中声明另一个int b,请尝试在A.CPP中使用它,链接器将投诉:
B.CPP:

#include <iostream>
using namespace std;
extern char a[50];
extern int b;

A.CPP:

#include <iostream>
using namespace std;
int a[100];
int main() {
    b=3; //using a variable unknown by this scope
    cout << "Hello World" << endl;
}

编译时,您将得到:

g++ a.cpp b.cpp
a.cpp: In function ‘int main()’:
a.cpp:7:5: error: ‘b’ was not declared in this scope
     b=3;
     ^

全局变量默认情况下具有外部链接,因此在声明被忽略之前的external,您所拥有的是double类型的另一个变量的声明。因此,对于链接器而言,double a[50]是一个与A.CPP中声明的变量完全分开的,因为它们处于分离范围,没有冲突,因此没有投诉。