Dear All,
I have found a build problem with an application which I have reduced to the
following test case:
$ cat foomain.cc
//
// g++ foomain.cc foo01.cc foo02.cc -o foo.out
//
// g++ -c foomain.cc
// g++ -c foo01.cc
// g++ -c foo02.cc
//
// g++ foomain.o foo01.o foo02.o -o foo.out
//
int main()
{
return 0;
}
$ cat foo01.cc
#include "foo.hh"
MYCLASS_INSTANTIATE_TYPES
$ cat foo02.cc
#include "foo.hh"
MYCLASS_INSTANTIATE_TYPES
$ cat foo.hh
#ifndef ONCE_FOO_H_
#define ONCE_FOO_H_
template<typename Value_t>
class MyClassBase
{
public:
class ClassWrapper;
MyClassBase();
~MyClassBase();
};
template<typename Value_t>
class MyClassBase<Value_t>::ClassWrapper
{
friend class MyClassBase<Value_t>;
public:
ClassWrapper() {}
};
#define MYCLASS_INSTANTIATE(g) g(int)
#define MYCLASS_INSTANTIATE_BASE(type) \
template class MyClassBase<type>;
#define MYCLASS_INSTANTIATE_TYPES \
MYCLASS_INSTANTIATE(MYCLASS_INSTANTIATE_BASE)
#endif
This test should be build as
g++ foomain.cc foo01.cc foo02.cc -o foo.out
or
g++ -c foomain.cc
g++ -c foo01.cc
g++ -c foo02.cc
g++ foomain.o foo01.o foo02.o -o foo.out
Now what happens is this:
Building on *** MAC OSX *** with gcc45, gcc46, gcc47 installed by means of
MacPorts, fails as
$ g++ foomain.o foo01.o foo02.o -o foo.out
duplicate symbol MyClassBase<int>::ClassWrapper::ClassWrapper() in:
foo01.o
foo02.o
duplicate symbol MyClassBase<int>::ClassWrapper::ClassWrapper() in:
foo01.o
foo02.o
ld: 2 duplicate symbols for architecture x86_64
collect2: error: ld returned 1 exit status
instead it builds (on MAC OSX) using clang++,
$ clang++ foomain.o foo01.o foo02.o -o foo.out
$
It also builds on Cygwin with gcc-4.5.3 and gcc-4.8 snapshot.
It builds on GNU/Linux (K)Ubuntu with gcc-4.6.3
So the question is: does the above code violate some C++ standard?
Maybe is it wrong the way as the inline (the class ClassWrapper constructor in
the above code) functions are used?
TIA,
Angelo.