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 grep
ed all my source code.
I have no idea what's going on. I'll be glad for any clue开发者_C百科.
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... :)
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.
精彩评论