Multiple Definition Error in C++
When a function or variable has several definitions in various source files, the linking procedure results in a multiple-definition error. To ensure the program’s uniformity and accuracy, the linker expects only one definition across all source files.
Typically, the error looks like this:
It is crucial for each C++ developer to comprehend this error’s cause and know how to fix it.
Factors that Lead to Multiple Definition Errors in C++
Multiple definition errors can happen in your C++ code for several reasons as discussed below:
1: Multiple Definitions of the Same Function or Variable in a Source File
If you accidentally define the same function or variable multiple times in the same source file, you will encounter a multiple-definition error.
2: Function or Variable Defined in a Header file
When a function or variable is declared in a header file and that header file is referenced by numerous source files, any source file that has a header will also contain a definition for the function or variable. This generates the error of multiple definitions.
3: Declaring the Same Function or Variable Multiple Times in the Same Source file
If you accidentally declare the same function or variable multiple times in the same source file, you will encounter a multiple-definition error when linking. This is because the linker expects only one definition for each function or variable across all source files.
Fix Error with Multiple Definitions of a Function in C++
The following techniques can be used to fix multiple definition errors in C++:
1: Utilize Function Prototypes and External Variables
One technique to fix multiple definition errors in C++ is to declare a function or variable using function prototypes or external variables, rather than specifying them in a header file. By doing so, the function or variable will only be defined once in the source file, thus avoiding the error.
The following is a code syntax for the above solution.
#ifndef HEADER_H
#define HEADER_H
extern int sub(int num1, int num2);
#endif
// source.cpp
#include "header.h"
int sub(int num1, int num2)
{
return num1 - num2;
}
In the above syntax, the function sub is declared in the header file using the extern keyword, which indicates that it is defined elsewhere. The actual definition is then provided in the source file. The #ifndef HEADER_H and #define HEADER_H lines include guards that ensure the header file is included only once in the same source file to avoid redefining the function.
2: Utilize Static Functions or Variables
If a function or variable is only used in one source file, declare it as static. This restricts its scope to the current source file, and the linker will not consider it during linking. By doing so, you ensure that the function or variable is only defined once and cannot be accessed from other files.
Declaring a function or variable as static restricts its scope to the current source file and ensures that it is only defined once, making your code more modular and easier to maintain
Additionally, if you have multiple functions in different files, you can easily utilize them in any other project.
Consider the following code syntax as an example:
static int once_used_function()
{
// ...
}
In the above syntax, the “static” keyword is used to define a function called “once_used_function”. This function can only be accessed within the same source file and cannot be accessed from other files that are linked with this source file. This ensures that the function is only defined once and cannot be modified or accessed accidentally from other parts of the program.
3: Implement Inline Functions
Consider using inline functions for frequently called, short functions. This will eliminate the need for a separate definition, as the compiler can replace the function call with the function’s code directly.
Consider the following code syntax as an example:
inline int sub(int num1, int num2)
{
return num1 - num2;
}
In the above syntax, the “inline” keyword is used to define a function called “sub”, which takes two integer arguments and returns their difference. By defining this function as inline, the compiler will substitute the function call with the actual function code at compile time, eliminating the need for a separate function definition.
4: Utilize Namespaces
By using namespaces, you can prevent the linker from finding multiple definitions with the same name. The namespaces provide a way to group related declarations and definitions in a single named scope, making it easier to organize and manage large codebases.
Consider the following code syntax as an example:
namespace source_code_1
{
int sub(int num1, int num2)
{
return num1 - num2;
}
}
// source_code_2.cpp
namespace source_code_2
{
int sub(int num1, int num2)
{
return num1 - num2;
}
}
In the above syntax, two different source files have a function called “sub” with the same signature. To prevent naming conflicts, each function is defined within a separate namespace: “source_code_1” and “source_code_2”. This way, the functions can be accessed from within their respective namespaces without causing naming conflicts. When calling the function from other parts of the codebase, you would need to specify the namespace to indicate which version of the function you want to call.
Conclusion
When programmers and developers define and use the same function twice, the system becomes confused, leading to the typical error of multiple definitions of C++ functions. Because C++ can show unexpected mistakes and defects in files that appear to be correct, developers enjoy a dynamic experience working with it. Therefore, this guide explained the multiple definitions of functions error in C++, supplied the solution syntax, and debugged the mistake.