I am aware of how ODR, linkage, static
, and extern "C"
work with functions. But I am not sure about visibility of types since they cannot be declared static
and there are no anonymous namespaces in C.
In particular, I would like to know the validity of the following code if compiled as C and C++
// A.{c,cpp}
typedef struct foo_t{
int x;
int y;
} Foo;
static int use_foo()
{
Foo f;
f.x=5;
return f.x;
}
// B.{c,cpp}
typedef struct foo_t{
double x;
} Foo;
static int use_foo()
{
Foo f;
f.x=5.0;
return f.x;// Cast on purpose
}
using the following two commands (I know both compilers autodetect the language based on extensions, hence the different names).
g++ -std=c++17 -pedantic -Wall -Wextra a.cpp b.cpp
gcc -std=c11 -pedantic -Wall -Wextra a.c b.c
Versions 8.3 happily compile both without any errors. Clearly, if both struct symbols have external linkage, there is ODR violation because the definitions are not identical. Yes, compiler is not required to report it, hence my question because neither did.
Is it valid C++ program?
I do not think so, that is what anonymous namespaces are for.
Is it valid C program?
I am not sure here, I have read that types are considered static
which would make the program valid. Can someone please confirm?
C,C++ Compatibility
If these definitions were in public header files, perhaps in different C libraries, and a C++ program includes both, each also in a different TU, would that be ODR? How can one prevent this? Does extern "C"
play any role?