I am trying to execute following code using g++ and getting incomplete type error
#include <stdio.h>
struct try_main{
union{
struct try_inner_one{
int fl;
float g;
}one;
struct try_inner_two{
char a;
}two;
}un;
int chk;
};
void func(struct try_inner_one o){
printf("%d\n",o.fl);
}
int main(){
struct try_main z = {{1,2},3};
func(z.un.one);
return 0;
}
Error:
union.c: In function ‘void func(try_inner_one)’:
union.c:15:6: error: ‘o’ has incomplete type
void func(struct try_inner_one o){
^
union.c:15:18: error: forward declaration of ‘struct try_inner_one’
void func(struct try_inner_one o){
^
union.c: In function ‘int main()’:
union.c:20:16: error: parameter 1 of ‘void func(try_inner_one)’ has incomplete type ‘try_inner_one’
func(z.un.one);
Above code is successfully getting compiled with gcc
What is the reason for this error and how to fix this
Thanks
C and C++ have different scoping rules. The full name of the type in C++ isn’t struct try_inner_one
, since the type definition is nested inside the unnamed union inside try_main
.1
If you want to write code that works equally in both C and C++, pull the type definition to the top level:
struct try_inner_one {
int fl;
float g;
};
struct try_inner_two {
char a;
};
struct try_main {
union {
struct try_inner_one one;
struct try_inner_two two;
} un;
int chk;
};
1 The fully qualified name of this type can’t be spelled in C++ since the type it’s nested inside is unnamed. You could give a name to the union type, that would allow you to spell the fully qualified name of try_inner_one
in C++. However, that name wouldn’t be legal C code, since C doesn’t have a scope resolution operator.
If you want to keep the nested type definition you could give the union a name (in the following, union_name
) and do the following to keep the code compiling for both C and C++:
// (Type definition omitted.)
#ifdef __cplusplus
using try_inner_one = try_main::union_name::try_inner_one;
#else
typedef struct try_inner_one try_inner_one;
#endif
void func(try_inner_one o){
printf("%d\n", o.fl);
}