Link question

Discussion in 'C++' started by firegun9@yahoo.com.tw, Jun 14, 2005.

  1. Guest

    I am not a newbie C++, but I haven't coded multiple files project under
    g++.
    Here is my quesiont:

    b.h
    ////////////////////
    #ifndef b_h
    #define b_h

    class b{
    int b1;
    public:
    b(){}
    void set(int b1_);
    };

    void b::set(int b1_)
    {
    b1=b1_;
    }

    #endif




    a.h
    ===========================
    #include "b.h"

    class a{
    b* b_ptr;
    public:
    void set(b & b_obj);
    };

    void a::set(b & b_obj)
    {
    b_ptr=&b_obj;
    }


    main.cpp
    ////////////////////////////
    #include "a.h"
    #include "b.h"

    int main()
    {
    a a_obj;
    b b_obj;

    a_obj.set(b_obj);

    return 0;
    }

    For these 3 files, I can successfully compile and link by using "g++
    main.cpp".
    However, if I separate a.h into a.h and a.cpp, like here:
    a.h
    ===========================
    #include "b.h"

    class a{
    b* b_ptr;
    public:
    void set(b & b_obj);
    };

    a.cpp
    /////////////////////////
    #include "a.h"

    void a::set(b & b_obj)
    {
    b_ptr=&b_obj;
    }

    then I use the command "g++ a.cpp main.cpp", I got a link error
    "ld: fatal: symbol 'b::set(int)' is multiply-defined:
    (file /var/tmp/ccUoZBm0.o type=FUNC; file /var/tmp/ccG0aQup.o
    type=FUNC)"

    and if I also separate b.h into b.h and b.cpp in the same way, the
    error is gone.

    What's going on here?
    I just want to separate one of the files because in my real project,
    there's only one .h file is so long.
    , Jun 14, 2005
    #1
    1. Advertising

  2. wrote:
    > I am not a newbie C++, but I haven't coded multiple files project under
    > g++.
    > Here is my quesiont:
    >
    > b.h
    > ////////////////////
    > #ifndef b_h
    > #define b_h
    >
    > class b{
    > int b1;
    > public:
    > b(){}
    > void set(int b1_);
    > };
    >
    > void b::set(int b1_)


    If you want to keep the _definitions_ of your functions in a header,
    declare them 'inline', or define them in the class definition (where
    they are 'inline' implicitly).

    > {
    > b1=b1_;
    > }
    >
    > #endif
    >
    >
    >
    >
    > a.h
    > ===========================
    > #include "b.h"
    >
    > class a{
    > b* b_ptr;
    > public:
    > void set(b & b_obj);
    > };
    >
    > void a::set(b & b_obj)
    > {
    > b_ptr=&b_obj;
    > }
    >
    >
    > main.cpp
    > ////////////////////////////
    > #include "a.h"
    > #include "b.h"
    >
    > int main()
    > {
    > a a_obj;
    > b b_obj;
    >
    > a_obj.set(b_obj);
    >
    > return 0;
    > }
    >
    > For these 3 files, I can successfully compile and link by using "g++
    > main.cpp".
    > However, if I separate a.h into a.h and a.cpp, like here:
    > a.h
    > ===========================
    > #include "b.h"
    >
    > class a{
    > b* b_ptr;
    > public:
    > void set(b & b_obj);
    > };
    >
    > a.cpp
    > /////////////////////////
    > #include "a.h"
    >
    > void a::set(b & b_obj)
    > {
    > b_ptr=&b_obj;
    > }
    >
    > then I use the command "g++ a.cpp main.cpp", I got a link error
    > "ld: fatal: symbol 'b::set(int)' is multiply-defined:
    > (file /var/tmp/ccUoZBm0.o type=FUNC; file /var/tmp/ccG0aQup.o
    > type=FUNC)"
    >
    > and if I also separate b.h into b.h and b.cpp in the same way, the
    > error is gone.
    >
    > What's going on here?


    You're putting its definition in more than one module. No surprises.

    > I just want to separate one of the files because in my real project,
    > there's only one .h file is so long.


    The number of '.h' files doesn't matter. What matters is in how many
    '.cpp' files you're including it. Just think about it. What you do,
    essentially, is duplicate all the code in all the files where you include
    the header. '#include' directive is nothing but a text processing stunt.

    V
    Victor Bazarov, Jun 14, 2005
    #2
    1. Advertising

  3. Guest

    Well, I think I find the answer.

    Every .o file will contain the implematitions of the files it included.
    In my example, if I have 4 files, "b.h", "a.h", "a.cpp", "main.cpp",
    there would be "a.o" and "main.o". Both of them will have the function
    implementation writed in "b.h".( because they both can see "b.h") In
    the linking stage, this would cause a duplicate definition problem when
    the linker tries to link "a.o" and "main.o" together.

    The solution to this is to split "b.h" into "b.h" and "b.cpp" in the
    same way as "a.h".
    In this way, the implementation of class b will be only in "b.o", "a.o"
    and "main.o" will contain the information in "b.h" which is only the
    declartion of class b. When the three objects are linked together, the
    three object "b.o", "a.o" and "main.o" will contain the implementations
    of theirselves.

    Another workable situation is having "b.h", "b.cpp", "a.h" and
    "main.cpp".
    In this situation "b.o" contains class b's declaration and
    implementation, "main.o" contains class b's declaration and class a's
    declaration and implementation. Declarations can be overlapped in
    different object files, however, implementation of each class would be
    only appear once in corresponding object file.

    To Victor:
    Use inline for functions in class b is indeed work, but the reason is
    not like that you say here. Inline function just tell the compiler to
    append the definition of the function into where the function is being
    called instead of go into the address of the function in the linking
    stage which is the way how function is called in implementation of
    functions in a .cpp file. The reason work in my example is because
    there will be no implementation of class b in any .o object, so there's
    no multiple-definition problem.

    I may not be express very well in my poor English, if you have any
    comments please feel free to send me.
    , Jun 14, 2005
    #3
  4. Guest

    , Jun 14, 2005
    #4
  5. wrote:
    > [...]
    > To Victor:
    > Use inline for functions in class b is indeed work, but the reason is
    > not like that you say here.


    I don't say any reason.

    > Inline function just tell the compiler to
    > append the definition of the function into where the function is being
    > called instead of go into the address of the function in the linking
    > stage which is the way how function is called in implementation of
    > functions in a .cpp file. The reason work in my example is because
    > there will be no implementation of class b in any .o object, so there's
    > no multiple-definition problem.


    That's not necessarily so. Inline functions are treated differently than
    non-inline ones. It has to "merge" all the definitions of the same inline
    function into one (or discard all but one, it doesn't matter, really).
    Such operation ("merging" or "discarding") is not attempted for normal,
    non-inline functions.

    > [..]


    V
    Victor Bazarov, Jun 14, 2005
    #5
    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. Kevin Spencer

    Re: Link Link Link DANGER WILL ROBINSON!!!

    Kevin Spencer, May 17, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    817
    Kevin Spencer
    May 17, 2005
  2. Graham Thomson
    Replies:
    3
    Views:
    462
    Eki Y. Baskoro
    Dec 18, 2003
  3. Dan M
    Replies:
    5
    Views:
    421
  4. kolesdz
    Replies:
    9
    Views:
    530
    Blinky the Shark
    Aug 22, 2007
  5. Marina Limeira

    LINK with another link

    Marina Limeira, Feb 7, 2006, in forum: ASP .Net Web Services
    Replies:
    0
    Views:
    115
    Marina Limeira
    Feb 7, 2006
Loading...

Share This Page