I'm using GCC 8.1.0 / binutils 2.30 (I plan to upgrade to latest stuff in the next few weeks or so...), on GNU/Linux Intel 64bit.
I have a templated class C that required its type T to have operator bool() defined in order to work properly. I want to use that with a enum class so clearly that doesn't work for me. However I had an idea: I changed the implementation of the templated class so that instead of "if (t)" it uses "if (!!t)" then I created an operator!(T). I made it static inline like this: static inline bool operator!(T t) { return t != T::EMPTY; } When I compile "normally" this all works fantastically. But, when I compile using a "unity" build, I'm getting multiple definition errors: ld: error: libFoo.a(unity_2.cxx.o): multiple definition of 'operator!(T)' ld: libFoo.a(unity_12.cxx.o): previous definition here If you're not familiar with "unity" builds basically the build system will generate a meta-source file (above called things like unity_2.cxx or unity_12.cxx etc.) and compile that: the only thing in the meta- source file are includes of other source files: #include "File1.cpp" #include "File2.cpp" ... The goal is to improve compile times (at the expense of compiling more stuff when something changes obviously). I don't understand why I'm getting multiple definition errors. And it gets even stranger: when I nm my library, sure enough I see: libFoo.a:unity_12.cxx.o:0000000000003ef0 T operator!(T) libFoo.a:unity_9.cxx.o:0000000000003190 T operator!(T) libFoo.a:unity_8.cxx.o:0000000000003640 T operator!(T) libFoo.a:unity_2.cxx.o:0000000000005d80 T operator!(T) But!! When I nm the individual cxx.o files none of these operator symbols appear, at all! It's like they were created by the ar command, which is just: ar qc libFoo.a .... Which seems bizarre to me. Is this a bug in ... something ... either the compiler or binutils? Or, is my trick above not valid for some reason?