In C++ a struct (class, its members, etc...) has external linkage, meaning that if you have a struct of the same name with a different definition in another unit, that is breaking One Definition Rule.
a class, which is a type, does not have a linkage, instead it is referring to the linkage of the symbols defined in the class scope (but not the linkage of an object made using the class). This includes static members and methods and non-static methods, but not non-static members as they are only part of the class type definition and do not additionally declare / define actual symbols.
How is a symbol in anonymous namespace different than a symbol marked as static?
Can't have a static struct.
Isn't it enough to define the struct in .cc file instead of a header to make it invisible for other compilation units?
For example the following seems to work just fine:
> cat test2.h
#pragma once
int bar(int);
> cat test2.cc
#include "test2.h"
struct test {
int x;
};
int bar(int x) {
test t;
t.x = x;
return t.x;
}
> cat test.cc
#include "test2.h"
struct test {
int a;
int b;
};
int main() {
test t;
t.a = bar(0);
t.b = 1;
return 0;
}
> g++ -c -I. test2.cc
> g++ -c -I. test.cc
> g++ -I. test.o test2.o
> ./a.out
If I change test.cc to:
> cat test.cc
#include "test2.h"
struct test2 {
int a;
int b;
};
int main() {
test t;
t.x = bar(0);
return 0;
}
Then the compilation fails with:
> g++ -c -I. test.cc
test.cc:9:5: error: unknown type name 'test'; did you mean 'test2'?
test t;
^~~~
test2
test.cc:3:8: note: 'test2' declared here
struct test2 {
^
test.cc:10:7: error: no member named 'x' in 'test2'
t.x = bar(0);
~ ^
2 errors generated.
Well, yes, but sadly no.
In C++ a struct (class, its members, etc...) has external linkage, meaning that if you have a struct of the same name with a different definition in another unit, that is breaking One Definition Rule.
What does it mean in practise? Why is my first example compiling and working?
I guess that answers my qustion:
```
a class, which is a type, does not have a linkage, instead it is referring to the linkage of the symbols defined in the class scope (but not the linkage of an object made using the class). This includes static members and methods and non-static methods, but not non-static members as they are only part of the class type definition and do not additionally declare / define actual symbols.
```
Adding a member function like this:
> cat test.cc
#include "test2.h"
struct test {
int a;
int b;
int foo();
};
int test::foo() {
return 1;
}
int main() {
test t;
t.a = bar(0);
t.b = t.foo();
return 0;
}
> cat test2.cc
#include "test2.h"
struct test {
int x;
int foo();
};
int test::foo() {
return 2;
}
int bar(int x) {
test t;
t.x = x;
return t.foo();
}
Causes a compilation/linking error:
> g++ -I. test.o test2.o
duplicate symbol '__ZN4test3fooEv' in:
test.o
test2.o
ld: 1 duplicate symbols
clang: error: linker command failed with exit code 1 (use -v to see invocation)