Symbol already defined acting differently for class methods?

Discussion in 'C++' started by blazb, Oct 22, 2013.

  1. blazb

    blazb Guest

    Why does the linker (gcc, msvc) not fail for the example below?

    It complains for multiple definitions of function bar, but not for multiple definitions of function foo in class Foo.


    "a.cpp"

    #include <stdio.h>

    void bar() {
    puts("bar from a.cpp");
    }

    struct Foo {
    char a[20];
    void foo(){
    puts("foo from a.cpp");
    }
    };

    void test_b();

    int main()
    {
    printf("sizeof(Foo) in a.cpp: %d\n", sizeof(Foo));
    Foo().foo();
    bar();
    test_b();
    return 0;
    }

    "b.cpp"

    #include <stdio.h>

    struct Foo {
    char a[20];
    void foo(){
    puts("foo from b.cpp");
    }
    };

    //void bar() { puts("bar from b.cpp"); } // error: symbol already defined

    void test_b()
    {
    printf("sizeof(Foo) in b.cpp: %d\n", sizeof(Foo));
    Foo().foo();
    // bar();
    }
    blazb, Oct 22, 2013
    #1
    1. Advertising

  2. blazb

    sg Guest

    Am 22.10.2013 15:20, schrieb blazb:
    > Why does the linker (gcc, msvc) not fail for the example below?
    >
    > It complains for multiple definitions of function bar, but not for multiple definitions of function foo in class Foo.


    That's because foo is defined inside a class and therefore implicitly
    inline. The one definition rule makes an exception for inline functions
    (as well as function templates and static data members of class templates).
    sg, Oct 22, 2013
    #2
    1. Advertising

  3. blazb

    Guest

    On Tuesday, October 22, 2013 3:48:33 PM UTC+2, sg wrote:
    > Am 22.10.2013 15:20, schrieb blazb:
    >
    > > Why does the linker (gcc, msvc) not fail for the example below?

    >
    > >

    >
    > > It complains for multiple definitions of function bar, but not for multiple definitions of function foo in class Foo.

    >
    >
    >
    > That's because foo is defined inside a class and therefore implicitly
    >
    > inline. The one definition rule makes an exception for inline functions
    >
    > (as well as function templates and static data members of class templates).


    Thanks for yout prompt reponse.

    However, its not clear to me, why the same member function is called from call in a and call in b.

    with
    g++ a.cpp b.cpp
    foo from a.cpp is called in all cases.

    and with
    g++ b.cpp a.cpp
    foo from b.cpp is called in all cases.

    thanks
    , Oct 22, 2013
    #3
  4. blazb

    Guest

    On Tuesday, October 22, 2013 4:02:16 PM UTC+2, wrote:
    > On Tuesday, October 22, 2013 3:48:33 PM UTC+2, sg wrote:
    >
    > > Am 22.10.2013 15:20, schrieb blazb:

    >
    > >

    >
    > > > Why does the linker (gcc, msvc) not fail for the example below?

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > It complains for multiple definitions of function bar, but not for multiple definitions of function foo in class Foo.

    >
    > >

    >
    > >

    >
    > >

    >
    > > That's because foo is defined inside a class and therefore implicitly

    >
    > >

    >
    > > inline. The one definition rule makes an exception for inline functions

    >
    > >

    >
    > > (as well as function templates and static data members of class templates).

    >
    >
    >
    > Thanks for yout prompt reponse.
    >
    >
    >
    > However, its not clear to me, why the same member function is called from call in a and call in b.
    >
    >
    >
    > with
    >
    > g++ a.cpp b.cpp
    >
    > foo from a.cpp is called in all cases.
    >
    >
    >
    > and with
    >
    > g++ b.cpp a.cpp
    >
    > foo from b.cpp is called in all cases.
    >
    >
    >
    > thanks


    ah, nvm. This was the case only for compilation with -O0, but works ok with -O1,2 and 3.

    thanks
    , Oct 22, 2013
    #4
  5. <> wrote:
    [cleaned up quoting mess]
    > On Tuesday, October 22, 2013 4:02:16 PM UTC+2, wrote:
    >> On Tuesday, October 22, 2013 3:48:33 PM UTC+2, sg wrote:
    >>> Am 22.10.2013 15:20, schrieb blazb:
    >>>> Why does the linker (gcc, msvc) not fail for the example below?
    >>>>
    >>>> It complains for multiple definitions of function bar, but not for
    >>>> multiple definitions of function foo in class Foo.
    >>>
    >>> That's because foo is defined inside a class and therefore implicitly
    >>> inline. The one definition rule makes an exception for inline functions
    >>> (as well as function templates and static data members of class templates).

    >>
    >> Thanks for yout prompt reponse.
    >>
    >> However, its not clear to me, why the same member function is called
    >> from call in a and call in b.
    >>
    >> with
    >> g++ a.cpp b.cpp
    >> foo from a.cpp is called in all cases.
    >>
    >> and with
    >> g++ b.cpp a.cpp
    >> foo from b.cpp is called in all cases.
    >>
    >> thanks

    >
    > ah, nvm. This was the case only for compilation with -O0, but works ok with -O1,2 and 3.


    Careful!
    Classes an inline functions can be defined in multiple translation units,
    but all definitions must be the same. Everything else is undefined behavior
    and _anything_ can happen.

    Tobi
    Tobias Müller, Oct 22, 2013
    #5
  6. blazb

    Guest

    On Thursday, October 24, 2013 5:27:48 AM UTC+2, Richard Damon wrote:
    > On 10/22/13 9:20 AM, blazb wrote:
    >
    > > Why does the linker (gcc, msvc) not fail for the example below?

    >
    > >

    >
    > > It complains for multiple definitions of function bar, but not for multiple definitions of function foo in class Foo.

    >
    > >

    >
    > >

    >
    >
    >
    > As has been mentioned, Foo::foo is declared (implicitly) inline. Now
    >
    > inline functions may need to generate a "real" version of the function
    >
    > to call when it can't be made inline for some reason, and the compiler
    >
    > is obligated to make this work. Typically, the compiler will mark the
    >
    > object code generated in some way so the linker will throw out the extra
    >
    > copies automatically.


    Thanks for all replies.
    , Oct 24, 2013
    #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. Renuka
    Replies:
    2
    Views:
    334
    Jason S
    Dec 5, 2003
  2. dee
    Replies:
    6
    Views:
    539
  3. =?Utf-8?B?THluZXJz?=
    Replies:
    0
    Views:
    1,377
    =?Utf-8?B?THluZXJz?=
    Dec 5, 2005
  4. baumann@pan
    Replies:
    1
    Views:
    731
    Richard Bos
    Apr 15, 2005
  5. Jim Cain
    Replies:
    7
    Views:
    138
    Brian Candler
    Jul 18, 2003
Loading...

Share This Page