Reputation: 1411
As I have understood, a class can be defined in multiple translation units aslong they're identical. With that in mind, consider the following examples:
//1.cpp
class Foo{
public:
int i;
};
void FooBar();
void BarFoo(){
Foo f;
}
int main(){
FooBar();
BarFoo();
}
//2.cpp
class Foo{
public:
std::string s;
};
void FooBar(){
Foo f;
}
This compiles and I don't get a crash.
If I do the following changes:
//1.cpp
Foo FooBar();
//2.cpp
Foo FooBar(){
Foo f;
return f;
}
I get a crash. Why does one result in a crash and the other doesn't. Also, am I not violating ODR in the first example? If I am, why does it compile ok?
Upvotes: 1
Views: 1228
Reputation: 258618
The program is ill-formed for the reason you stated. The compiler is not required a diagnostics, but I don't see a point in discussing reasons for a crash in an ill-formed program.
Still, let's do it:
The first example probably doesn't crash because FooBar
's behavior doesn't affect the run of main
. The method is called, it does something, and that's it.
In the second example, you attempt to return a Foo
. FooBar
returns the version of Foo
defined in 2.cpp
. main
appears in 1.cpp
so it expects the version of Foo
defined in 1.cpp
, which is a completely different version - different members, sizes. You most likely get a corruption on the destructor. (just a guess)
6) There can be more than one definition of a class type [...] in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. [...]
- each definition of D shall consist of the same sequence of tokens;
[...]
Upvotes: 2
Reputation: 10557
Here is how compiler/linker work:
Compiler translates cpp file having the headers that are provided. It generates an .obj file. In your case the o.bj file will have references to data-struct Foo
. And there will be no any other details.
Linker links .obj files together. It compares only the string names. In your obj files your have the same Foo
. Names match. For the linker this is the same thing.
After that you start your program. Most likely it will crash. To be more specific it will show undefined behavior. It can enter infinite loop, show strange messages, etc.
It is your responsibility to provide identical headers or definitions in the cpp files into translations of every cpp file. Existing software tools cannot check this for you. This is how it works.
Upvotes: 1