c++ - C++中的多重定义错误

标签 c++ compilation linkage

我正在编写一个 C++ 程序,其中每个文件都有自己的一组全局变量声明。这些文件中的大多数都使用在其他文件中使用 extern 定义的全局变量。

这是一个类似于我的程序的例子:

main.cpp

#include "stdafx.h"
#include <iostream>
#include "Other_File.cpp"

int var1;
int var2;

int main()
{
    var1 = 1;
    var2 = 2;
    otherFunction();
    var4 = 4; // From Other_File.cpp

    std::cout << var1 << " " << var2 << " " << var3 << " " << var4 << std::endl;

    return(0);
}

Other_File.cpp

extern int var1;
extern int var2;

int var3;
int var4;

void otherFunction()
{
     var3 = var1 + var2;
     var4 = 0;
}

当我在 Visual Studio (Windows) 中构建此代码时,一切运行良好且输出正确。但是当我尝试在 Linux 上使用 g++ 构建时,我收到以下错误:

g++ -o Testing Testing.o Other_File.o Other_File.o:(.bss+0x0): multiple definition of var3' Testing.o:(.bss+0x0): first defined here Other_File.o:(.bss+0x4): multiple definition ofvar4' Testing.o:(.bss+0x4): first defined here Other_File.o: In function otherFunction()': Other_File.cpp:(.text+0x0): multiple definition of otherFunction()' Testing.o:Testing.cpp:(.text+0x0): first defined here collect2: ld returned 1 exit status make: *** [Testing] Error 1

这是因为我在主文件中“包含”了另一个文件吗?

如果不是,我的代码有什么问题?

编辑:这是我的 g++ 生成文件的内容:

Testing: Testing.o Other_File.o
    g++ -o Testing Testing.o Other_File.o

Testing.o: Testing.cpp
    g++ -c -std=c++0x Testing.cpp

Other_File.o: Other_File.cpp
    g++ -c -std=c++0x Other_File.cpp

clean:
    rm *.o Calculator

最佳答案

不要#include 一个源文件到另一个源文件中。在某些时间和地点,这样做是可以的,但只有不到 0.001% 的程序需要这样做。

您应该做的是创建一个 文件,其中包含两个源文件中所需内容的声明

那么你的代码应该是这样的:

  1. main.cpp源文件

    #include "stdafx.h"
    #include <iostream>
    #include "Other_File.h"  // Note inclusion of header file here
    
    int var1;
    int var2;
    
    int main()
    {
        var1 = 1;
        var2 = 2;
        otherFunction();
        var4 = 4; // From Other_File.cpp
    
        std::cout << var1 << " " << var2 << " " << var3 << " " << var4 << std::endl;
    }
    
  2. other_file.cpp源文件,就像你现在拥有的一样

  3. other_file.h头文件,新建一个文件

    #pragma once
    
    // Declare the variables, so the compiler knows they exist somewhere
    extern int var3;
    extern int var4;
    
    // Forward declaration of the function prototype
    void otherFunction();
    

然后两个源文件将分别编译并链接在一起以形成最终的可执行文件。这个链接步骤是您的构建失败的地方。它会注意到 other_source.cpp 中定义的变量是在从该源文件创建的目标文件中定义的,但是由于您将它包含在 main.cpp 源文件中目标文件也是从该源文件创建的。

这就是您需要了解 translation units 的原因,这是编译器实际看到的。一个 C++ 源文件经过许多 phases of translation ,每个人都在做自己的特殊部分。 翻译单元大致是一个包含所有 header 的源文件。

这也是学习 preprocessor #include directive 的一个很好的理由做。它基本上将包含的文件按原样插入到正在预处理的源文件中。在 #include 指令所在的位置,经过预处理后它将成为包含文件的内容,这就是编译器将看到的内容。

关于c++ - C++中的多重定义错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37578441/

相关文章:

c++ - MSVC 中的 "interface"关键字是什么?

android - 如何使用平台和构建工具在 RHEL linux 上安装 Android sdk

r - 启用内存分析的成本是多少?

c++ - c++ 中的多重定义错误和解决此问题的解决方案

c++ - 如何创建 typedef 结构的前向声明

c++ - 如何将 vector<uint8_t> 转换为 unsigned char*

qt - 在Qt Creator中自动重建依赖关系

c++ - constexpr 和静态 constexpr 全局变量的区别

c++ - gcc 4.4 与 gcc >4.4 中的默认链接模型

c++ - 无法将 ifstream 对象声明为我类(class)的成员