I was messing around and expecting the following to blow up when I tried to compile it but to my shock it totally works. Can someone please explain to me how/why the following works.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 | // foo.h
#ifndef FOO_H
#define FOO_H
#ifdef __cplusplus
#include <iostream>
extern "C" {
#endif
typedef struct foo {
float x;
float y;
float z;
#ifdef __cplusplus
float w;
inline foo operator+(const foo& addend) {
foo result = {
x + addend.x,
y + addend.y,
z + addend.z,
w + addend.w
};
return result;
}
#endif
}foo;
#ifdef __cplusplus
} // End C linkage
inline std::ostream& operator<<(std::ostream &os, const foo &inst) {
os << inst.x << ' ' << inst.y << ' ' << inst.z << ' ' << inst.w << '\n';
return os;
}
#endif
#endif // FOO_H
//cfoo.c
#include "foo.h"
extern foo c_foo;
foo c_foo = { 3.0f, 3.0f, 3.0f };
// main.cpp
#include "foo.h"
#include <iostream>
extern "C" foo c_foo;
static foo cpp_foo = { 1.0f, 2.0f, 3.0f, 4.0f };
int main(){
foo a = cpp_foo + c_foo;
std::cout << c_foo;
std::cout << cpp_foo;
std::cout << a;
float w = a.w;
std::cout << w << std::endl;
std::getchar();
return 0;
}
|
This certainly seems like a disaster waiting to happen, especially since sizeof() gives a different value depending on if it is used in a .c or .cpp file. I was expecting a multiple definition error but MSVC, Clang, and G++ all compiled and ran the program just fine. I would like to understand why.