I have some simple codes here:
// main.cpp
#include <iostream>
#include "foo.h"
int main() {
Foo foo;
foo.spam();
std::cout << "In main: sizeof (Foo) = " << sizeof (Foo) << std::endl;
return 0;
}
// foo.h
#ifndef FOO_H
#define FOO_H
class Foo {
public:
int bar;
void spam();
};
#endif
// foo.cpp
#include <iostream>
#include "foo.h"
void Foo::spam() {
std::cout << "sizeof (Foo) = " << sizeof (Foo) << std::endl;
}
The program is simple and we can easily foresee the output:
sizeof (Foo) = 4
In main: sizeof (Foo) = 4
But as for the include directives, the preprocessor simply replace them with the included file content, so the declaration of Foo
appears in both main.cpp
and foo.cpp
.
What if we manually put the declaration of Foo
in main.cpp
and modify it on purpose like this?
// main.cpp
#include <iostream>
// #include "foo.h" replaced with declaration of foo
#ifndef FOO_H
#define FOO_H
class Foo {
public:
int bar, baz, qux, eggs; // added some members
void spam();
};
#endif
int main() {
Foo foo{111, 222, 333, 444};
foo.spam();
std::cout << "In main: sizeof (Foo) = " << sizeof (Foo) << std::endl;
std::cout << "foo.qux = " << foo.qux << std::endl; // try to access the newly added qux member
return 0;
}
Now the two declarations of Foo
in main.cpp
and foo.cpp
are different, but the program still compiles and runs! The output becomes
sizeof (Foo) = 4
In main: sizeof (Foo) = 16
foo.qux = 333
What the hell is happening here?! Why can Foo
have two different declarations in one program? Why this even compiles?