Question

I'm having a project which compiles perfectly with gcc, but fails to compile under Greenhills Integrity environment.

The problem boils down to this three files:

MyVector.cpp // contains function testVector
MyVector.hpp // contains template vector<>
SomeFile.cpp

MyVector.hpp contains template-class for a vector, and MyVector.cpp contains a testing function unrelated to MyVector.hpp's templates.

Now, when I'm using MyVector.hpp's vector templates in SomeFile.cpp, somehow, the function testVector gets injected into SomeFile.cpp. When I cease to use vector in SomeFile.cpp (I'm still #include'ing it of course, I'm just not instantiate the template there) it works perfectly.

Moreover when I injected a warning into function testVector, the compiler showed the warning when I compiled SomeFile.cpp!

Moreover, the build system recompiles SomeFile.cpp when I'm changing things in MyVector.cpp.

When I'm deleting the testVector function from MyVector.cpp and move it to a new NewFile.cpp - it compiles.

No, I didn't include the cpp file by mistake, honest, I double checked it, and greped all my source code.

I have no idea what's going on. I'll be glad for any clue.

Was it helpful?

Solution

Green Hills uses the Edison Design Group front-end, and until very recently (say, MULTI 5.0 or maybe even 5.2) the compiler turned on --implicit_include by default. Here's the Edison documentation for that option:

--implicit_include
--no_implicit_include
-B
     Enable or disable implicit inclusion of source files as a method of
     finding definitions of template entities to be instantiated. -B is
     equivalent to --implicit_include. The default behavior is specified
     by the configuration flag DEFAULT_IMPLICIT_TEMPLATE_INCLUSION_MODE.
     See the section of this chapter on template instantiation. This
     option is valid only in C++ mode.

Your problem will very likely be fixed if you pass --no_implicit_include on the compiler command line. (If that fails, try -W0,--no_implicit_include or :compiler.args=--no_implicit_include, either of which will pass the option straight through to the front-end without (much) censorship by the driver. Passing --std or --STD might also help; I don't remember.)

Implicit inclusion is a terribly stupid idea today, but it was a convenient way to provide template functionality back in the '90s. Today, there are standard and well-known ways of satisfying the One Definition Rule, and this "implicit inclusion" hack just gets in the way of law-abiding C++tizens such as yourself.

Now go on, ask me about prelinking... :)

OTHER TIPS

When you say you 'inject a warning' are you using a #pragma directive? A #pragma directive is meant to be seen during compile time, not during run time.

When you say the function 'testVector gets injected into SomeFile.cpp', how is this observed? Do you get a compiler or linker error saying that the function was previously defined?

Are you compiling gcc for Integrity OS or gcc for x86 Linux?
Integrity works very differently from Linux, and the type of Integrity project matters. You can build a monolithic Integrity kernel or an Integrity kernel supporting dynamic download. Additionally the Integrity C and C++ runtime libraries are different from Linux.

How are you implementing vector? I'm thinking you're implementing this in MyVector.cpp and including MyVector.cpp at the end of MyVector.hpp. If this is the case, including MyVector.hpp in SomeFile.cpp will trigger a rebuild of SomeFile.cpp when you change MyVector.cpp. I'd suggest run it through the pre-processor and see where the testVector() is being included from.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top