Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
189 views
in Technique[技术] by (71.8m points)

compilation - Multiple definitions error in C++

I'm writing a C++ program where each file has it's own set of global variable declarations. Most of these files make use of global variables that were defined in the other files using extern.

Here's an example similar to my program:

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;
}

When I build this code in Visual Studio (Windows), everything runs fine and the output is correct. But when I attempt to build using g++ on Linux I receive the following error:

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

Is this because I'm "including" the other file in my main file?

If not what's the issue with my code?

Edit: This is the content of my Makefile for 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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Don't #include a source file into another source file. There times and places when that is okay, but only in like less than 0.001% of all programs is that needed.

What you should do is create a header file which contains declarations of the things needed in both source files.

Then your code would look like this:

  1. main.cpp source file

    #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 source file, just like you have it now

  3. other_file.h header file, a new file

    #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();
    

Both source files would then be compiled separately and linked together to form the final executable. This linking step is where your build fails. It will notice that the variables defined in other_source.cpp are defined in the object file created from that source file, but since you include it into the main.cpp source file then the object file created from that source file as well.

This is why you need to learn about translation units, which is what the compiler actually see. A C++ source file goes through many phases of translation, each one doing its own special part. Roughly a translation unit is a single source file with all the headers included.

This is also a good reason to learn what the preprocessor #include directive does. It basically inserts the included file, as is, into the source file being preprocessed. Where the #include directive was, after preprocessing it will be the contents of the included file, and that is what the compiler will see.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...