Thread: Linking error

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    271

    Linking error

    Hi all,

    In an ongoing effort to wean myself off of visual studio, I'm compiling and linking with g++ 4.0.3 and sometimes, it gets just too arcane.

    Here's the problem I've run into now.

    Let's say there's a header file "a.h" with source "a.cc".

    In "a.h" a class has been defined:
    Code:
    class A
    {
    
    //some basic declarations
    //definitions were placed in a.cc
    }A; //note the instantiation here
    Then, there's "b.cc" which holds the main routine.

    Code:
    #include "a.h"
    
    int main(... yada yada
    Here's how I run g++ (actually, I'm doing this with GNU make, but since the basics are the same, I guess it doesn't really matter).
    Code:
    g++ -c a.cc -o a.o
    g++ -c b.cc -o b.o
    g++ -o a a.o b.o
    Doing this gives me the following error:
    Code:
    a.o:(.bss+0x0): multiple definition of 'A'
    b.o:(.bss+0x0): first defined here
    I remembered vaguely that the order of the object files might matter so I switched "a.o" and "b.o" and it still didn't work.

    The only way I can get it to work is by getting rid of the instantiation at the end of the class declaration like this:
    Code:
    class A
    {
    ...gobble gobble
    };
    What I don't understand is why I can't instantiate objects or declare variables in a header file if I want to compile them separately? The GNU g++ manual isn't clear on this, and I'm looking into Stroustrup's book, but his section on linking was pitifully small.

    As always, help appreciated.
    Last edited by cunnus88; 05-03-2007 at 11:41 PM.

  2. #2
    "Why use dynamic memory?"
    Join Date
    Aug 2006
    Posts
    186
    why would you ever instantiate directly after class definition ?
    "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, it blows away your whole leg."-Bjarne Stroustrup
    Nearing the end of finishing my 2D card game! I have to work on its 'manifesto' though <_<

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    So stop instantiating things in the header.
    Certainly stop instantiating things at the same time as you declare the type.

    In the .h
    Code:
    class A
    {
    
        //some basic declarations
    
        //definitions were placed in a.cc
    
    };  // All done declaring the class.
    
    extern A A;  // there's an A somewhere
    In ONE .cc file only, have
    Code:
    A A;  // a global instance of an A
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    Okay, I'm still thinking as if I were coding in visual studio, but in those days, I could declare, instantiate, define, whatever in the header.

    So I guess the correct answer is: You're never supposed to instantiate or define in the header?

    Then why does the following command work, even if there's some kind of instantiation in "a.h"?
    Code:
    g++ b.cc
    And I guess the answer to that would be: the precompiler is just dumping the code of "a.h" into "b.cc" and then compiling and linking from there?

    Anyway, enlightenment would be appreciated.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    You can get away with doing an awful lot when you only have one header file, and one source file. Then it doesn't matter where you instantiate things.

    When you have multiple source files, all including the same header, that's when you have to be careful.

    > the precompiler is just dumping the code of "a.h" into "b.cc" and then compiling and linking from there?
    That's all #include is, an inline cut/paste operation just before the compiler sees the code.

    You can see all the gory details by doing
    g++ -E b.cc > temp.txt
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    Thanks.

    Now that I think of it, it makes sense, since if you have two instantiations of a class in two different object files with the same name, it would throw the linker off.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Beginner Needs help in Dev-C++
    By Korrupt Lawz in forum C++ Programming
    Replies: 20
    Last Post: 09-28-2010, 01:17 AM
  2. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  3. pointer to array of objects of struct
    By undisputed007 in forum C++ Programming
    Replies: 12
    Last Post: 03-02-2004, 04:49 AM
  4. Stupid compiler errors
    By ChrisEacrett in forum C++ Programming
    Replies: 9
    Last Post: 11-30-2003, 05:44 PM
  5. Couple C questions :)
    By Divx in forum C Programming
    Replies: 5
    Last Post: 01-28-2003, 01:10 AM