Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error with multiple definitions of function

I am trying to relearn C++ after taking an intro course a few years ago and I’m having some basic problems. My current problem occurs when trying to use a friend function. Here is my code in 2 files.

First:

// fun.cpp  #include <iostream> using namespace std;  class classA {     friend void funct(); public:     classA(int a=1,int b=2):propa(a),propb(b){cout<<"constructor\n";} private:     int propa;     int propb;     void outfun(){         cout<<"propa="<<propa<<endl<<"propb="<<propb<<endl;     } }; void funct(){                     // ERROR HERE     cout<<"enter funct"<<endl;     classA tmp(1,2);     tmp.outfun();     cout<<"exit funct"<<endl; } 

Second:

// mainfile.cpp #include <iostream> #include "fun.cpp" using namespace std;  int main(int nargin,char* varargin[]) {     cout<<"call funct"<<endl;     funct();     cout<<"exit main"<<endl;     return 0; } 

The error I am getting is "multiple definition of `funct()'". Am I using the wrong syntax when declaring it as a friend function?

like image 722
Adad Dayos Avatar asked Jul 28 '13 03:07

Adad Dayos


People also ask

How do you solve multiple definition main errors?

Error Fix. The main function is the entry point for the C++ program execution. The fix for the error is to scan the source files listed in the build log and remove the unwanted main routines in the respective files. We can have one definition of the main function for the project to run.

What is multiple definition error in C?

If you put a definition of a global variable in a header file, then this definition will go to every . c file that includes this header, and you will get multiple definition error because a varible may be declared multiple times but can be defined only once.

When there are multiple definitions with the same function name?

Answer: The multiple definitions with the same function name is called Function Overloading. The only difference among those functions is their parameter list which helps the compiler to recognize which function is being executed.

How do you avoid multiple definitions in C++?

Put int A::val=0; in a cpp file. If you use C++17 another option is to make it an inline variable. Then you don't need to define it anywhere outside the class definition.


2 Answers

Here is a highly simplified but hopefully relevant view of what happens when you build your code in C++.

C++ splits the load of generating machine executable code in following different phases -

  1. Preprocessing - This is where any macros - #defines etc you might be using get expanded.

  2. Compiling - Each cpp file along with all the #included files in that file directly or indirectly (together called a compilation unit) is converted into machine readable object code.

    This is where C++ also checks that all functions defined (i.e. containing a body in { } e.g. void Foo( int x){ return Boo(x); }) are referring to other functions in a valid manner.

    The way it does that is by insisting that you provide at least a declaration of these other functions (e.g. void Boo(int); ) before you call it so it can check that you are calling it properly among other things. This can be done either directly in the cpp file where it is called or usually in an included header file.

    Note that only the machine code that corresponds to functions defined in this cpp and included files gets built as the object (binary) version of this compilation unit (e.g. Foo) and not the ones that are merely declared (e.g. Boo).

  3. Linking - This is the stage where C++ goes hunting for stuff declared and called in each compilation unit and links it to the places where it is getting called. Now if there was no definition found of this function the linker gives up and errors out. Similarly if it finds multiple definitions of the same function signature (essentially the name and parameter types it takes) it also errors out as it considers it ambiguous and doesn't want to pick one arbitrarily.

The latter is what is happening in your case. By doing a #include of the fun.cpp file, both fun.cpp and mainfile.cpp have a definition of funct() and the linker doesn't know which one to use in your program and is complaining about it.

The fix as Vaughn mentioned above is to not include the cpp file with the definition of funct() in mainfile.cpp and instead move the declaration of funct() in a separate header file and include that in mainline.cpp. This way the compiler will get the declaration of funct() to work with and the linker would get just one definition of funct() from fun.cpp and will use it with confidence.

like image 96
Mohit Chugh Avatar answered Oct 19 '22 05:10

Mohit Chugh


The problem is that if you include fun.cpp in two places in your program, you will end up defining it twice, which isn't valid.

You don't want to include cpp files. You want to include header files.

The header file should just have the class definition. The corresponding cpp file, which you will compile separately, will have the function definition.

fun.hpp:

#include <iostream>  class classA {     friend void funct(); public:     classA(int a=1,int b=2):propa(a),propb(b){std::cout<<"constructor\n";} private:     int propa;     int propb;     void outfun(){         std::cout<<"propa="<<propa<<endl<<"propb="<<propb<< std::endl;     } }; 

fun.cpp:

#include "fun.hpp"  using namespace std;  void funct(){     cout<<"enter funct"<<endl;     classA tmp(1,2);     tmp.outfun();     cout<<"exit funct"<<endl; } 

mainfile.cpp:

#include <iostream> #include "fun.hpp" using namespace std;  int main(int nargin,char* varargin[]) {     cout<<"call funct"<<endl;     funct();     cout<<"exit main"<<endl;     return 0; } 

Note that it is generally recommended to avoid using namespace std in header files.

like image 43
Vaughn Cato Avatar answered Oct 19 '22 07:10

Vaughn Cato