I am working on a project where there is a .h file that contains the following lines:
File1.h
typedef struct {
int a;
} MyData;
typedef struct {
MyData MyData;
} MyDataContainer;
This is compiled using gnu99 standard without any issues. However, if i include File1.h in a C++ file compiled using gcc standard gnu++17, i get errors related to the type name MyData and the instance MyData having the same name. I am not really used to working in C. Is there a reason to have the same type name as the instance name? I cannot change the C file, are there workarounds to #include File1.h in a C++ file?
Thank you in advance for your help.
File1.h compiles with no errors. When i link the library compiled using gnu99 in a library compiled in C++, it throws errors.
Preamble: In C++, the code in the question is ill-formed, no diagnostic required; see Variable with same name as type - which compiler is right? for Standard references.
If you cannot modify the C file then there are no seamless, well-defined workarounds .
It may be possible to disable the error message, in which case the behaviour of the program will be formally undefined, but is likely to work correctly:
-Wno-changes-meaning
.-fms-extensions
, but that has other effects.Failing that, you will have to make an intermediate layer between the C code and the C++ code, with a new function to wrap every C function the C++ code needed to call with a MyData argument; for example:
// MyKludge.h
typedef struct {
Type1 myVar1;
Type2 myVar2;
} MyData;
typedef struct {
MyData foo;
TypeA myVarA;
TypeB myVarB;
} MyDataContainer2;
void File1Func(MyDataContainer2 *x);
// MyKludge.c
#include "File1.h"
#include "MyKludge.h"
void File1FuncWrapper (MyDataContainer2 *x)
{
// Technically undefined behaviour but will probably work
File1Func( (MyDataContainer *)x );
// Definitely well-defined but could be inefficient depending on compiler
MyDataContainer y;
y.MyData = x->foo;
y.MyVarA = x->MyVarA;
y.MyVarB = x->MyVarB;
File1Func( &y );
x->foo = y.MyData; // If func might change object
x->MyVarA = y.MyVarA;
x->MyVarB = y.MyVarB;
}