Search code examples
c++linkergreenhills

Strange behavior for X.cpp/X.hpp files in Integrity


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.


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... :)