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

2

9

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

Impoverished answered 15/9, 2015 at 9:50 Comment(3)
Are the functions inline, or do the real headers just contain declarations? This why I never understand why C doesn't have namespaces. Without templates and overloading, there is nothing complicated, and they would solve all the naming conflicts and render the use of stupid prefixes obsolete.Rouvin
Is this C or C++? For C++ use this tutorial: tutorialspoint.com/cplusplus/cpp_namespaces.htmTobiastobie
you can not get rid of this situation without changing these header files in c.If you change one of methods in header files as static it will compile or use namespaces in c++ for these methods. if you want to use one of the header files and do not want to change headers, use #ifndef structure for including one of the header files.Lucky
E
3

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.

Eskimo answered 15/9, 2015 at 13:47 Comment(0)
S
8

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.

Schleswigholstein answered 15/9, 2015 at 11:55 Comment(3)
This only works if the functions are inline functions. If the headers just declare the functions and the implementation is linked in, it will not work.Rouvin
@Rouvin It also happens in unnamed namespaces? (I don't know, just asking).Derwood
It is not working for the given scenario, this solves for inline functions only...Impoverished
E
3

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.

Eskimo answered 15/9, 2015 at 13:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.