当外部变量在其他文件中声明不同时,如何使g ++生成警告?

时间:2017-09-24 03:23:47

标签: c++ g++ compiler-warnings extern

我有两个文件:

a.cpp

#include <iostream>

using namespace std;

extern double a[50];

b.cpp

g++ a.cpp b.cpp

显然在两个文件中存在“a”的冲突声明。但是当我跑步时

for (double i = 0; i <= colNumberWithTop; i++) {
    //printing the top column
    if (i == 0){
     System.out.printf("%-10s", "Interest Rate");  
     for (double k = 0; k <= rowNumber; k++) {
         currentYears = (firstYears + (incYears * i));
         System.out.printf("%10s", currentYears + " Years");
     }
     System.out.println(); 
    } else if (i > 0) {
      //finding annual interest rate for printing, and monthly interest rate as a decimal for math
      currentAnnInt = (startAnnInt + (incRate * i));
      currentMonthInt = ((currentAnnInt/100)/12);
      System.out.printf("%10.2f%%", currentAnnInt*100);
      for (double k = 0; k <= rowNumber; k++) {
           monthsToPay = (startMonthInt + (monthIncRate * i));
           annuityAmt = annuityCalc(currentMonthInt, monthsToPay);
           currentPayment = (loanAmt * annuityAmt);
           System.out.printf("%10.2f", currentPayment);
      }
      System.out.println();

编译默默成功。

有什么方法可以让g ++抱怨冲突(通过警告或错误)?

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

3 个答案:

答案 0 :(得分:2)

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

如果您创建“a.h”文件,则可以将其包含在“a.cpp”和“b.cpp”中。随后的编译将导致错误,因为标题中的extern double a[50];声明与“a.cpp”中的int a[50];定义之间的类型不匹配。

答案 1 :(得分:0)

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

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

请注意,这不是“阴影”,这就是影子标志无效的原因。阴影是指在内部作用域中重复使用相同的名称,其中名称已存在于外部作用域中,例如void f() { int x; { double x; } }。但是,两个不同的翻译单元不是重叠范围。

答案 2 :(得分:0)

从g ++“观点”来看,没有冲突。 变量double a[50]受限于b.cpp文件。由于{。{1}}存在于a.cpp中,因此您有错误的感觉,即您正在使用相同的变量。 在b.cpp中声明另一个,比如a尝试在a.cpp中使用它,链接器会抱怨:
b.cpp:

int b

<强> a.cpp:

#include <iostream>

using namespace std;

extern char a[50];
extern int b;

编译时,你会得到:

#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; ^ 被忽略,而您拥有的是另一个double类型变量的声明。因此,对于链接器,external是一个完全与a.cpp中声明的变量分开的变量,因为它们位于独立的范围内并且没有冲突,所以没有抱怨。