Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid variable/function conflicts from two libraries in C++

I have similar scenario as explained below:

I have one header file first.h It has a function :

char* getName();

and associated cpp file first.cpp having function definition

char* getName(){return "first";}

and the second header file second.h it has the function:

char* getName();

associated cpp file second.cpp having function definition

char* getName(){return "second";}

Now there is a main() function:

#include "first.h"
#include "second.h"

int main(){
return 0;
}

when I include those .h files, compiler give an error at the function getName() as it is conflicting.

How to get rid of this problem without changing .h files

like image 642
Jyo the Whiff Avatar asked Sep 15 '15 09:09

Jyo the Whiff


2 Answers

You can use namespaces when including those header files:

In your cpp file:

namespace first
{
    #include "first.h"
}

namespace second
{
    #include "second.h"
}

Then you can use the functions as the following:

...
first::getName();
second::getName();
...

Edit: Thanks to Jens' comment this only works if the functions are inline. If the functions are not inline and you really can't change the header files you can create "wrapper" header files for those functions:

File wrapper-first.h:

namespace first
{
    char* getName();
}

File wrapper-first.cpp:

#include "wrapper-first.h"
#include "first.h"

char* first::getName()
{
    return ::getName();
}

...and create the same for the second header file. Then you just include the wrpper-include files in your cpp file and use the code as above.

like image 138
Thomas Sparber Avatar answered Sep 20 '22 15:09

Thomas Sparber


This will be tricky. Both libraries will contain an getName symbol. The linker will resolve the getName symbol using the first library providing it. This happens regardless of what you do with the headers. You're just lucky that the compiler already complained, and gave you a clear error.

Thomas Barder's idea will hide the compiler problem. It won't fix the linker issue. first::getName will still use ::getName from the second library, or vice versa.

The necessary solution is to have first::getName in its own library. This library should link against the first library only. The main executable links against your helper library and the original second library. The linker no longer has duplicate symbols, because it's invoked twice. When building the helper library, ::getName comes unambiguously from the first library. When building the main executable it unambiguously comes from the second library.

like image 44
MSalters Avatar answered Sep 21 '22 15:09

MSalters