Why this doesn't violate One definition rule and how the linker resolves this

N

Ninan

I am using gcc compiler


gcc B.o Main.o -lMyLib

//A.h
class A {
public:
A();
void abc ();
void bcd ();
};

Class A is defined in MyLib ie (A.cpp) is in MyLib and it also contains
A.h

Main.cpp also #include "A.h"

Now if change the A.h #included in Main.cpp only as

//A.h changed only in Main.cpp

//A.h
class A {
public:
A();
void abc ();
void bcd ();
Test () {std::cout << "hello world " << std::endl; }

};

This still compiles and I can invoke the Test in Main.cpp. This
compiles even if Test is non-inline.
Does n't this violate the One Definition rule of C++. Also how does the
linker resolve this
 
P

Phlip

Ninan said:
This still compiles and I can invoke the Test in Main.cpp. This
compiles even if Test is non-inline.
Does n't this violate the One Definition rule of C++. Also how does the
linker resolve this

Compilers rarely enforce that rule. The C languages use definitions and
compilation models that are all based - indirectly - on the original C
linker, which was amazingly broken. Our language uses .h files, instead of
modules, essentially because nobody wanted to fix and upgrade that linker.

So to this day linkers for C languages permit all kinds of excesses. For
example, you can sometimes say 'extern int foo = 42;' in every translation
unit, and never write 'int foo = 42;' anywhere, and the compiler will
accept this and create storage for foo.
 
T

Tomás

Ninan posted:
I am using gcc compiler


gcc B.o Main.o -lMyLib

//A.h
class A {
public:
A();
void abc ();
void bcd ();
};

Class A is defined in MyLib ie (A.cpp) is in MyLib and it also contains
A.h

Main.cpp also #include "A.h"

Now if change the A.h #included in Main.cpp only as

//A.h changed only in Main.cpp

//A.h
class A {
public:
A();
void abc ();
void bcd ();
Test () {std::cout << "hello world " << std::endl; }

};

This still compiles and I can invoke the Test in Main.cpp. This
compiles even if Test is non-inline.
Does n't this violate the One Definition rule of C++. Also how does the
linker resolve this


Just because a particular compiler compiles it doesn't mean it's not bad
code.

For instance, make an inline function like this:

inline int GetNumber()
{
static int blah = 4;

return ++blah;
}

Put it in a header file and include it in two cpp files.

Now make another inline function, but change it:

inline int GetNumber()
{
static int blah = 242352235;

return ++blah;
}


Now inlcude this in a few cpp files.

Most, if not all, compilers will compile that with no errors.

Bottom Line: The Standard says you can't do that.

-Tomás
 
J

Jack Klein

I am using gcc compiler


gcc B.o Main.o -lMyLib

//A.h
class A {
public:
A();
void abc ();
void bcd ();
};

Class A is defined in MyLib ie (A.cpp) is in MyLib and it also contains
A.h

Main.cpp also #include "A.h"

Now if change the A.h #included in Main.cpp only as

//A.h changed only in Main.cpp

//A.h
class A {
public:
A();
void abc ();
void bcd ();
Test () {std::cout << "hello world " << std::endl; }

};

This still compiles and I can invoke the Test in Main.cpp. This
compiles even if Test is non-inline.
Does n't this violate the One Definition rule of C++. Also how does the
linker resolve this

Yes, it violates the ODR. That means your program has undefined
behavior, and the C++ language places no requirements at all on the
results.

As to what your particular linker does, that is not an issue the
language either knows or cares about, and it is specific to your
linker. In any case, since you have broken the rules, once again C++
does not care what happens.
 

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

Forum statistics

Threads
473,770
Messages
2,569,585
Members
45,081
Latest member
AnyaMerry

Latest Threads

Top