Order of cpp files matters?

Discussion in 'C++' started by pooh, Jan 24, 2005.

  1. pooh

    pooh Guest

    I have a situation where the order of my cpp files in my g++ compile
    command line affects the program.

    Here is a simplified example:

    g++ -Wall -o test a.cpp b.cpp

    compiles, links and runs fine.

    g++ -Wall -o test b.cpp a.cpp

    compiles, and links fine (no errors or warnings) but returns a
    segmentation fault when run.

    I did not think that the order of the files mattered.
    g++ (GCC) 3.3.4 on Debian Linux 2.4.26-1-386
     
    pooh, Jan 24, 2005
    #1
    1. Advertising

  2. pooh

    Mike Wahler Guest

    "pooh" <> wrote in message
    news:3_0Jd.144571$KO5.33634@clgrps13...
    > I have a situation where the order of my cpp files in my g++ compile
    > command line affects the program.
    >
    > Here is a simplified example:
    >
    > g++ -Wall -o test a.cpp b.cpp
    >
    > compiles, links and runs fine.
    >
    > g++ -Wall -o test b.cpp a.cpp
    >
    > compiles, and links fine (no errors or warnings) but returns a
    > segmentation fault when run.


    We have no way of discerning the problem without seeing
    the code. Some possibilites (these are only guesses)
    are:

    Somewhere your code is producing undefined behavior
    (symptoms of which can include 'seems to work'), which
    is being manifested differently with different 'build
    orders'.

    Perhaps you have global objects in different translation
    units which depend upon a certain order of creation
    (this order is not specified by the language).

    But again, nobody can know for sure without seeing the
    code.


    > I did not think that the order of the files mattered.


    It can.

    -Mike
     
    Mike Wahler, Jan 24, 2005
    #2
    1. Advertising

  3. pooh wrote:
    > I have a situation where the order of my cpp files in my g++ compile
    > command line affects the program.
    >
    > Here is a simplified example:
    >
    > g++ -Wall -o test a.cpp b.cpp
    >
    > compiles, links and runs fine.
    >
    > g++ -Wall -o test b.cpp a.cpp
    >
    > compiles, and links fine (no errors or warnings) but returns a
    > segmentation fault when run.
    >
    > I did not think that the order of the files mattered.
    > g++ (GCC) 3.3.4 on Debian Linux 2.4.26-1-386


    When linking, some linkers only perform a single pass.
    This may have something to do with external dependencies,
    things referenced outside of a given translation unit.

    In some linkers, the object files have to be listed more
    than once in order to satisfy undefined symbols.

    Try this:
    g++ -Wall -c -o a.o a.cpp
    g++ -Wall -c -o b.o b.cpp
    g++ -o test a.o b.o

    also try this:
    g++ -o test b.o a.o


    --
    Thomas Matthews

    C++ newsgroup welcome message:
    http://www.slack.net/~shiva/welcome.txt
    C++ Faq: http://www.parashift.com/c -faq-lite
    C Faq: http://www.eskimo.com/~scs/c-faq/top.html
    alt.comp.lang.learn.c-c++ faq:
    http://www.comeaucomputing.com/learn/faq/
    Other sites:
    http://www.josuttis.com -- C++ STL Library book
    http://www.sgi.com/tech/stl -- Standard Template Library
     
    Thomas Matthews, Jan 24, 2005
    #3
  4. pooh

    pooh Guest

    Thomas Matthews wrote:
    > pooh wrote:
    >
    >> I have a situation where the order of my cpp files in my g++ compile
    >> command line affects the program.
    >>
    >> Here is a simplified example:
    >>
    >> g++ -Wall -o test a.cpp b.cpp
    >>
    >> compiles, links and runs fine.
    >>
    >> g++ -Wall -o test b.cpp a.cpp
    >>
    >> compiles, and links fine (no errors or warnings) but returns a
    >> segmentation fault when run.
    >>
    >> I did not think that the order of the files mattered.
    >> g++ (GCC) 3.3.4 on Debian Linux 2.4.26-1-386

    >
    >
    > When linking, some linkers only perform a single pass.
    > This may have something to do with external dependencies,
    > things referenced outside of a given translation unit.
    >
    > In some linkers, the object files have to be listed more
    > than once in order to satisfy undefined symbols.
    >
    > Try this:
    > g++ -Wall -c -o a.o a.cpp
    > g++ -Wall -c -o b.o b.cpp
    > g++ -o test a.o b.o
    >
    > also try this:
    > g++ -o test b.o a.o
    >
    >

    I think found the cause of the problem but I'm uncertain as to the reason.

    (Sorry but I'm new to c++ so my terminology below may not be quite accurate)

    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();

    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.

    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? 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++).

    Thanks
     
    pooh, Jan 24, 2005
    #4
  5. pooh

    shez Guest

    pooh wrote:
    > 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? Seems odd to me but then again, I think global
    > variables should be avoided (and this is maybe one of the many

    reasons
    > why?).
    >


    Pooh,

    Try not to use global variables in your program. If you absolutely
    must access something globally, you can use the singleton pattern:

    YourClass& getMySingleton()
    {
    static YourClass object;
    return object;
    }

    Now you access your object through this function call, e.g.:

    getMySingleton().doSomething(...);

    This pattern ensures that your object is always fully constructed
    before it is used.


    > I'm tempted to pass all "globals" as parameters. Is this practical?
    >


    Not if you use the singleton pattern (see above).

    > What is a "translation unit". That term is new to me (as is c++).
    >
    > Thanks


    To put it simply, the translation unit is what your compiler sees after
    all your header files have been included. The compiler treats the
    whole thing as a single "file" and will generate object code (.o file)
    for it. Then the object code for all translation units will be linked
    to produce your executable file.

    -shez-
     
    shez, Jan 25, 2005
    #5
  6. pooh wrote:
    >

    [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.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Jan 25, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. DrUg13
    Replies:
    1
    Views:
    478
    DrUg13
    Feb 10, 2004
  2. Alex Vinokur
    Replies:
    7
    Views:
    413
    Greg Comeau
    Nov 15, 2004
  3. Vinu
    Replies:
    9
    Views:
    625
  4. www.hitechskill.com
    Replies:
    0
    Views:
    1,357
    www.hitechskill.com
    Apr 9, 2006
  5. SpaceMarine

    wonky <authorization> (order matters?)

    SpaceMarine, May 21, 2008, in forum: ASP .Net Security
    Replies:
    1
    Views:
    109
    Joe Kaplan
    May 21, 2008
Loading...

Share This Page