Symbol already defined acting differently for class methods?

B

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.


"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();
}
 
S

sg

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).
 
B

blaz.bratanic

Am 22.10.2013 15:20, schrieb blazb:




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
 
B

blaz.bratanic

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
 
T

Tobias Müller

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
 
B

blaz.bratanic

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,705
Latest member
Stefkari24

Latest Threads

Top