[Exception] Duplicate symbol error when using errinfo_api_function in static library

Dear readers,
I encountered a problem in my project when using *Boost.Exception* with the
predefined types errinfo_xyz in a library project. I have two classes
ClassA and ClassB in my library which both throw a boost::exception with
errinfo_api_function type in their implementation file (.cpp) These both
classes are compiled into a static library with the C/C++-Flags
-fvisibility=hidden.
Then I have a main.cpp which creates an instance of ClassA and ClassB and
links to the library which contains ClassA.o and ClassB.o. When I compile
the main.cpp I get the linker error duplicate symbol for the
errinfo_api_function object in ClassA.o and ClassB.o. If I remove the
visibility=hidden flag, it links without problems. I am not an expert on
the compiler flags, but I saw that many libraries use the visibility=hidden
flag so I think it would be good, if my lib could also use it.
For a better description I will show the sources for my project:
ClassA.h
-------------------------------------------------------------------------------------------------
#pragma once
#include

On Tue, Oct 1, 2013 at 2:16 AM, Georg Leidinger < georg.leidinger@googlemail.com> wrote:
Dear readers,
I encountered a problem in my project when using *Boost.Exception* with the predefined types errinfo_xyz in a library project. I have two classes ClassA and ClassB in my library which both throw a boost::exception with errinfo_api_function type in their implementation file (.cpp) These both classes are compiled into a static library with the C/C++-Flags -fvisibility=hidden. Then I have a main.cpp which creates an instance of ClassA and ClassB and links to the library which contains ClassA.o and ClassB.o. When I compile the main.cpp I get the linker error duplicate symbol for the errinfo_api_function object in ClassA.o and ClassB.o. If I remove the visibility=hidden flag, it links without problems. I am not an expert on the compiler flags, but I saw that many libraries use the visibility=hidden flag so I think it would be good, if my lib could also use it.
Honestly I have no idea why this would happen. Anyone? -- Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Hi Emil,
I was able to figure out some more information about the issue and I could
isolate it a little bit more. First it doesn't matter if it is a static or
a shared library. Second it is not directly related to the
*Boost.Exception*library but to the template class
*error_info* which is used to create the predefined errinfo_xyz types. It
is enough to instantiate the *errinfo_api_function* type in both
doSomething() methods in the both implementation files. I am not so good in
templates but I guess that the compiler creates the same symbol in both
object files (ClassA.o and ClassB.o) for the type *errinfo_api_function.* I
can see this via nm that I have the following line in both object files:
*ClassA.o*
*0000000000059860 s __ZTIN5boost21errinfo_api_function_E*
*
*
*ClassB.o*
*0000000000059870 s __ZTIN5boost21errinfo_api_function_E *
*
*
Now, when the linker tries to link ClassA.o and ClassB.o to the main.o the
both symbols clashes. But that would mean I could never use *Boost.Exception
* or any other template instantiated type in a library.
Best Regards
Georg
2013/10/2 Emil Dotchevski
On Tue, Oct 1, 2013 at 2:16 AM, Georg Leidinger < georg.leidinger@googlemail.com> wrote:
Dear readers,
I encountered a problem in my project when using *Boost.Exception* with the predefined types errinfo_xyz in a library project. I have two classes ClassA and ClassB in my library which both throw a boost::exception with errinfo_api_function type in their implementation file (.cpp) These both classes are compiled into a static library with the C/C++-Flags -fvisibility=hidden. Then I have a main.cpp which creates an instance of ClassA and ClassB and links to the library which contains ClassA.o and ClassB.o. When I compile the main.cpp I get the linker error duplicate symbol for the errinfo_api_function object in ClassA.o and ClassB.o. If I remove the visibility=hidden flag, it links without problems. I am not an expert on the compiler flags, but I saw that many libraries use the visibility=hidden flag so I think it would be good, if my lib could also use it.
Honestly I have no idea why this would happen. Anyone?
-- Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On Wed, Oct 2, 2013 at 3:06 PM, Georg Leidinger < georg.leidinger@googlemail.com> wrote:
Hi Emil,
I was able to figure out some more information about the issue and I could isolate it a little bit more. First it doesn't matter if it is a static or a shared library. Second it is not directly related to the * Boost.Exception* library but to the template class *error_info* which is used to create the predefined errinfo_xyz types. It is enough to instantiate the *errinfo_api_function* type in both doSomething() methods in the both implementation files. I am not so good in templates but I guess that the compiler creates the same symbol in both object files (ClassA.o and ClassB.o) for the type *errinfo_api_function.* I can see this via nm that I have the following line in both object files:
*ClassA.o* *0000000000059860 s __ZTIN5boost21errinfo_api_function_E* * * *ClassB.o* *0000000000059870 s __ZTIN5boost21errinfo_api_function_E *
Instantiating a template in two compilation units should not lead to link errors. That's why I can't understand why this happens. -- Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

It happens only if the library is build with the *LLVM 4.2* (I am using
XCode so it is the Apple LLVM 4.2, I don't know if there is something
different from the standard LLVM 4.2). If I choose the *LLVM GCC 4.2* no
errors are reported. Is this a bug in the LLVM compiler?
best
Georg Leidinger
2013/10/3 Emil Dotchevski
On Wed, Oct 2, 2013 at 3:06 PM, Georg Leidinger < georg.leidinger@googlemail.com> wrote:
Hi Emil,
I was able to figure out some more information about the issue and I could isolate it a little bit more. First it doesn't matter if it is a static or a shared library. Second it is not directly related to the * Boost.Exception* library but to the template class *error_info* which is used to create the predefined errinfo_xyz types. It is enough to instantiate the *errinfo_api_function* type in both doSomething() methods in the both implementation files. I am not so good in templates but I guess that the compiler creates the same symbol in both object files (ClassA.o and ClassB.o) for the type *errinfo_api_function.* I can see this via nm that I have the following line in both object files:
*ClassA.o* *0000000000059860 s __ZTIN5boost21errinfo_api_function_E* * * *ClassB.o* *0000000000059870 s __ZTIN5boost21errinfo_api_function_E *
Instantiating a template in two compilation units should not lead to link errors. That's why I can't understand why this happens.
-- Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

I found this *clang bug* http://llvm.org/bugs/show_bug.cgi?id=10113 which
seems to be related to the problem.
2013/10/3 Georg Leidinger
It happens only if the library is build with the *LLVM 4.2* (I am using XCode so it is the Apple LLVM 4.2, I don't know if there is something different from the standard LLVM 4.2). If I choose the *LLVM GCC 4.2* no errors are reported. Is this a bug in the LLVM compiler?
best Georg Leidinger
2013/10/3 Emil Dotchevski
On Wed, Oct 2, 2013 at 3:06 PM, Georg Leidinger < georg.leidinger@googlemail.com> wrote:
Hi Emil,
I was able to figure out some more information about the issue and I could isolate it a little bit more. First it doesn't matter if it is a static or a shared library. Second it is not directly related to the * Boost.Exception* library but to the template class *error_info* which is used to create the predefined errinfo_xyz types. It is enough to instantiate the *errinfo_api_function* type in both doSomething() methods in the both implementation files. I am not so good in templates but I guess that the compiler creates the same symbol in both object files (ClassA.o and ClassB.o) for the type *errinfo_api_function.* I can see this via nm that I have the following line in both object files:
*ClassA.o* *0000000000059860 s __ZTIN5boost21errinfo_api_function_E* * * *ClassB.o* *0000000000059870 s __ZTIN5boost21errinfo_api_function_E *
Instantiating a template in two compilation units should not lead to link errors. That's why I can't understand why this happens.
-- Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

I finally found a way to compile it with clang. I am using the pragma to
make the symbols for the Boost.Exception part not hidden like this:
#pragma GCC visibility push(default)
#include
I found this *clang bug* http://llvm.org/bugs/show_bug.cgi?id=10113 which seems to be related to the problem.
2013/10/3 Georg Leidinger
It happens only if the library is build with the *LLVM 4.2* (I am using XCode so it is the Apple LLVM 4.2, I don't know if there is something different from the standard LLVM 4.2). If I choose the *LLVM GCC 4.2* no errors are reported. Is this a bug in the LLVM compiler?
best Georg Leidinger
2013/10/3 Emil Dotchevski
On Wed, Oct 2, 2013 at 3:06 PM, Georg Leidinger < georg.leidinger@googlemail.com> wrote:
Hi Emil,
I was able to figure out some more information about the issue and I could isolate it a little bit more. First it doesn't matter if it is a static or a shared library. Second it is not directly related to the * Boost.Exception* library but to the template class *error_info* which is used to create the predefined errinfo_xyz types. It is enough to instantiate the *errinfo_api_function* type in both doSomething() methods in the both implementation files. I am not so good in templates but I guess that the compiler creates the same symbol in both object files (ClassA.o and ClassB.o) for the type *errinfo_api_function.* I can see this via nm that I have the following line in both object files:
*ClassA.o* *0000000000059860 s __ZTIN5boost21errinfo_api_function_E* * * *ClassB.o* *0000000000059870 s __ZTIN5boost21errinfo_api_function_E *
Instantiating a template in two compilation units should not lead to link errors. That's why I can't understand why this happens.
-- Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On 2 Oct 2013 at 17:21, Emil Dotchevski wrote:
*ClassA.o* *0000000000059860 s __ZTIN5boost21errinfo_api_function_E* * * *ClassB.o* *0000000000059870 s __ZTIN5boost21errinfo_api_function_E *
Instantiating a template in two compilation units should not lead to link errors. That's why I can't understand why this happens.
Instantiating a template in two compilation units is no different to defining a non-static function twice. Unless its symbols are marked as composable (weak on ELF, selectany on PE) the linker will error. The only portable way of marking symbols as composable in C++ is the "inline" keyword which is auto-added by a C++ compiler for functions defined inline in a class definition. Given that most modern C++ compilers don't really take much hinting from inline anymore, inline now really equals "set this symbol to weak/selectany" i.e. don't link error if I instantiate this more than once. My point is that instantiating a template in multiple compilation units needs all of its member functions to be marked inline in order to prevent link error. Or, as the OP has found, one can hack around the problem by overriding symbol visibility and forcing multiple copies in each compilation unit. Niall -- Currently unemployed and looking for work. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/

On 2 Oct 2013 at 14:48, Emil Dotchevski wrote:
Then I have a main.cpp which creates an instance of ClassA and ClassB and links to the library which contains ClassA.o and ClassB.o. When I compile the main.cpp I get the linker error duplicate symbol for the errinfo_api_function object in ClassA.o and ClassB.o. If I remove the visibility=hidden flag, it links without problems. I am not an expert on the compiler flags, but I saw that many libraries use the visibility=hidden flag so I think it would be good, if my lib could also use it.
Honestly I have no idea why this would happen. Anyone?
Throwable types must *always* be marked with attribute visibility default. I assume this has been done correctly, but if it hasn't that might help explain the problem. See my doc on the issue at http://gcc.gnu.org/wiki/Visibility. Note that throwable types, if with virtual function tables, may consist of more symbols than otherwise expected. Niall -- Currently unemployed and looking for work. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/

On Wed, Oct 2, 2013 at 4:20 PM, Niall Douglas
On 2 Oct 2013 at 14:48, Emil Dotchevski wrote:
Then I have a main.cpp which creates an instance of ClassA and ClassB and links to the library which contains ClassA.o and ClassB.o. When I compile the main.cpp I get the linker error duplicate symbol for the errinfo_api_function object in ClassA.o and ClassB.o. If I remove the visibility=hidden flag, it links without problems. I am not an expert on the compiler flags, but I saw that many libraries use the visibility=hidden flag so I think it would be good, if my lib could also use it.
Honestly I have no idea why this would happen. Anyone?
Throwable types must *always* be marked with attribute visibility default. I assume this has been done correctly, but if it hasn't that might help explain the problem. See my doc on the issue at http://gcc.gnu.org/wiki/Visibility.
These are not throwable types. For example, errinfo_api_function is not a throwable type. -- Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode
participants (3)
-
Emil Dotchevski
-
Georg Leidinger
-
Niall Douglas