简体   繁体   中英

Why does Declaring in header file and defining in file gives multiple definition error?

I am new to programming in c++. I had some better knowledge on JAVA. So using hackerrank I am trying to learn C++. To keep track of each program a sepearate entity I started using a Header File and Program file for each program or challenge. So I am trying to do the hackerrank exercise Input and Output ( https://www.hackerrank.com/challenges/cpp-input-and-output ). So I tried to implement my program in this manner;

InputAndOuput.h

 #ifndef INPUTANDOUTPUT_H_
 #define INPUTANDOUTPUT_H_

int arr[3];
int m;
int InputAndOutput();

#endif

InputAndOutput.cpp

#include "InputAndOutput.h"
#include<iostream>
#include<cmath>
#include<cstdio>

int InputAndOutput(){
     int arr[3];
     for(int i1 = 0; i1 < 3 ; i1++)
        std::cin >> arr[i1];
     for(int i = 0; i < 3 ; i++)
       m = m + arr[i];
     return m;
}

main.cpp

#include<iostream>
//#include<day1DataTypes>
#include<cmath>
#include<cstdio>
//#include "day1DataTypes.h"
#include "InputAndOutput.h"

int main()
{
    int k = InputAndOutput();   \\the error persists even the whole block is commented
    std::cout << k << std::endl ;
}

This one is giving the following errors;

Description Resource    Path    Location    Type
first defined here  Hackerrank      line 6  C/C++ Problem
first defined here  Hackerrank      line 8  C/C++ Problem
make: *** [Hackerrank] Error 1  Hackerrank          C/C++ Problem
multiple definition of `arr'    Main.cpp    /Hackerrank line 9  C/C++ Problem
multiple definition of `m'  Main.cpp    /Hackerrank line 12 C/C++ Problem

Please explain me what's wrong with this notation.BTW I am using eclipse and it's throwing error at compile time.

To explain the simplest problem first, let's take a look at the "int arr[3];"

For that variable declaration, it is declared and implemented in the InputAndOutput.h header.

Both main.cpp and InputAndOutput.cpp include the header file, thus implementing the variable twice.

To declare the variable, where it can be used in other files, you would use:

InputAndOutput.h

extern int arr[3];
extern int m;

InputAndOutput.cpp

int arr[3];
int m;

This tells the compiler that there are 2 variables, arr and m, which are being declared in the .h file, but are implemented in an external file, using the extern keyword.

Please note, that the code you posted in your question is merely C within C++ files.

In C++, it is discouraged to use global variables for storing data.

So, if you were to remove global variables and use c++ stl containers, you would have the following:

InputAndOutput.h

#include <array>
int32_t InputAndOutput(std::array<int32_t, 3>& arr, int32_t& m);

InputAndOutput.cpp

int32_t InputAndOutput(std::array<int32_t, 3>& arr, int32_t& m)
{    
     for(auto i1 = 0; i1 < 3 ; i1++)
         std::cin >> arr[i1];
     for(auto i = 0; i < 3 ; i++)
         m = m + arr[i];
     return m;
 }

main.cpp

int main()
{
    auto arr = std::array<int32_t, 3>{0,0,0};
    auto m = 0;
    const auto k = InputAndOutput(arr, m);
    std::cout << k << std::endl ;
}

Now, this should take care of most of your question, however, I don't see in your original code how you are getting input from std::cin since you don't prompt the user for input... and that leads to a bug.

Since you are learning C++, you should be learning Modern C++ and not C++98.

I would recommend that you read up on https://github.com/isocpp/CppCoreGuidelines

And, also check out Herb Sutter's website, with regard to Almost-Always-Auto at https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM