To illustrate the problem, we use a contrived program, consisting three components: main.cpp as the driver, and a pair of src1 and src2.

1
2
3
4
5
6
7
8
9
// main.cpp
#include "src1.h",
#include "src2.h"

int main() {
f1();
f2();
return 0;
}
1
2
3
4
5
// src1.h

#pragma once

void f1();
1
2
3
4
5
6
7
8
9
10
11
12
// src1.cpp
#include <iostream>

struct Test {
Test() {
std::cout << "src1 Test\n";
}
};

void f1() {
Test t;
}
1
2
3
4
5
// src2.h

#pragma once

void f2();
1
2
3
4
5
6
7
8
9
10
11
12
// src2.cpp
#include <iostream>

struct Test {
Test() {
std::cout << "src2 Test\n";
}
};

void f2() {
Test t;
}
1
2
3
$ clang++ hello.cc src1.cpp src2.cpp ; ./a.out
src1 Test
src1 Test

Note the msg for f2 is incorrect. A simple fix is to place the struct inside the function, so that both struct have internal linkage. For example for src1.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
// src1.cpp
#include <iostream>

void f1() {
struct Test {
Test() {
std::cout << "src1 Test\n";
}
};

Test t;
}
1
2
3
$ clang++ hello.cc src1.cpp src2.cpp ; ./a.out
src1 Test
src2 Test

This kind of bug is subtle and it has its counterpart in C as well – functions defined at top-level have external linkage. The quick fix in C is to mark them as static.