Structs with the same structure being equivalent for the correctness of access, while still denoting incompatible types, is useful.
Let's face it, if we have this:
void some_library_api(foo *object, int arg);
we want a diagnostic if we do
bar b;
some_library_api(&b, 42);
otherwise we are almost back to C with no prototypes.
We probably want that diagnostic even if it happens that both struct foo and struct bar are in scope and look identical.
Maybe they are accidentally identical. The program then compiles. A new version of the API comes out and things break. Needless tensions arise between the users and the API provider.
Let's face it, if we have this:
we want a diagnostic if we do otherwise we are almost back to C with no prototypes.We probably want that diagnostic even if it happens that both struct foo and struct bar are in scope and look identical.
Maybe they are accidentally identical. The program then compiles. A new version of the API comes out and things break. Needless tensions arise between the users and the API provider.