pooh said:
[snip]
In one of my class headers (.h file) I have an extern statement to allow
the class to be initialized globally.
(in my A.h file):
class A
{ <snip> }
extern A gclA;
I initialize a global object using this class at the end of the
corresponding cpp file.
(in my A.cpp file):
<snip>
A gclA();
Note: The above does not define the global object, but it
declares a function called gclA, which takes no parameters and
returnes an A object. You ment
A gclA;
But if I switch the g++ command line order of A.cpp with one that is
dependent on it (B.cpp) the program compiles and links but generates a
segmentation fault when run. The opposite order works fine.
Today I found that if I move the initialization of the global object
from A.cpp to main.cpp (which contains the main() function) then the
order of A.cpp and B.cpp no longer causes a problem.
All of this points to one possible conclusion:
There is something else wrong in your program.
It might be that you have an array overflow somewhere in your program
or you access memory with an invalid pointer or things like that.
The reason is:
Linking in different order or moving variables around don't alter
the logical structure of your program but they do alter the specific
memory layout of your program (where in memory are what things
located). You now have found that in specific memory layouts
your program crashes while in others it doesn't. The key to this
is: Usually things are not put in sequence in memory but the compiler
(or linker) inserts some padding bytes between them. In some of
these memory layouts your 'bug' cannot be seen, because you simply
alter some of those padding bytes und thus do no harm to the real
program or variables, while in other configurations
you overwrite vital program information which happens just to be
at those 'hot' areas, because of the specific memory layout.
I guess the logic is simply that the program linking somehow determines
when my global object gets initialized and if I get the order wrong the
dependent code fails?
Could also be:
If you have multiple global objects and their initialization
order is dependent on each other. Avoid such cases if possible.
You can easiliy detect things like that by putting breakpoints
on all constructors of all the global variables and see in
which order they get called.
Seems odd to me but then again, I think global
variables should be avoided (and this is maybe one of the many reasons
why?).
I'm tempted to pass all "globals" as parameters. Is this practical?
What is a "translation unit". That term is new to me (as is c++).
It is one unit that is fed to the compiler independent of all
other units. Usually it is a single cpp source code file.