Re: Help needed with strange compiler/linker behavior (boost, Green Hills)
I have a follow up (with some C++ content this time). I was able to
boil the problem down to a test case, and it doesn't have anything to
do with boost per se. I just had to mimic what was going on in boost's
date_generators.hpp file.
Consider this program with the following files:
//////////////// main.cpp:
void foo();
int main()
{
foo();
return 0;
}
/////////////// foo.cpp
#include <boost/template.h> // not the real boost....
void foo()
{
templatedClass<double> thing(0);
thing.tricky();
}
/////////////////// boost/template.h
template<typename T>
class baseClass
{
public:
virtual ~baseClass() {}
// note that this must be pure virtual to see the linker problem:
virtual void vFunc() = 0;
protected:
T array[4];
};
template<typename T>
class templatedClass : public baseClass<T>
{
public:
explicit templatedClass(int n) : n(n) {}
int tricky() const
{
return 0;
}
virtual void vFunc()
{
std::cout << n << std::endl;
}
private:
int n;
};
int innocentFreeFunction(int n);
///////////////////// boost/template.cpp (located in another
directory,
///////////////////// but still in the -I include search path:
#include <boost/template.h>
const int lookup[3] = { -1, 0, 1 };
int innocentFreeFunction(int n)
{
if (n >= 0 && n < 3)
{
return lookup[n];
}
return -100;
}
To summarize, we have a header file template.h and inside that header
file is a templated class that inherits from another templated base
class. This header file also declares a non-template non-member free
function.(innocentFreeFunction). innocentFreeFunction() is declared in
the header file, but its definition is found in another file,
template.cpp, which is even located in another directory (but still in
the -I include path that the compiler sees).
A source file, foo.cpp #includes template.h and uses the template
class. After compiling foo.cpp however, if you inspect foo.o with
their nm-like utility, you will find the complete code for
innocentFreeFunction inside foo.o. It appears the compiler, when
instructed to compile foo.cpp, is going off on its own and locating
template.cpp, compiling it, and including the object file in foo.o.
This behavior is quite surprising to us. We can verify this by
introducing a syntax error in template.cpp, and then trying to compile
just foo.cpp in their IDE. And indeed it leads to multiply defined
symbols when you try to link the entire project.
If you take the path that template.cpp is on out of the -I include
path, then everything is fine: we get a link with no errors. (!!!!)
Another useful point of information: this only occurs when virtual
functions are involved in the template class. If you remove all the
virtual functions, or if you don't make the base class vFunc() pure
virtual (give it a default empty implementation), the problem is not
seen.
I've written up a trouble report to the vendor. But if anyone else has
any insight into this behavior I'd love to hear it. Thanks!
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]