使用 g++ 编译时出现类型不完整错误
Incomplete type error when compiled with g++
我正在尝试使用 g++ 执行以下代码并出现类型不完整的错误
#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;
}
错误:
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);
以上代码已成功使用 gcc 进行编译
此错误的原因是什么以及如何解决此问题
谢谢
C 和 C++ 具有不同的作用域规则。 C++ 中类型的全名不是 struct try_inner_one
,因为类型定义嵌套在 try_main
.1
内的未命名联合中
如果您想编写在 C 和 C++ 中同样有效的代码,请将类型定义拉到顶层:
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 这种类型的完全限定名不能在 C++ 中拼写,因为它嵌套在里面的类型是 unnamed。您可以为联合类型命名,这样您就可以在 C++ 中拼写 try_inner_one
的完全限定名称。但是,该名称不是合法的 C 代码,因为 C 没有范围解析运算符。
如果您想保留嵌套类型定义,您可以为联合命名(在下文中,union_name
)并执行以下操作以保持代码为 C 和 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);
}
What is the reason for this error
原因是 try_inner_one
嵌套在 try_main
中嵌套的联合中,无法通过 C++ 中该联合之外的上下文中的非限定名称查找找到(与 C 不同)。
how to fix this
您可以在 C++ 中使用限定名称:
void func(decltype(try_main::un)::try_inner_one o){
如果你给工会起个名字就可以简化:
union u { // note the name
struct try_inner_one{
void func(try_main::u::try_inner_one o){
一个 cross-language 兼容的解决方案是定义彼此之外的结构,如 Kondrad Rudolph 的回答中所述。
一句警告:C++ 在如何访问联合体的非活动成员方面比 C 更严格。
看来您正在将程序编译为 C++ 程序。在这种情况下,结构 try_main
中的每个声明都具有此结构的范围。
所以你需要像这样声明函数
void func( decltype( try_main::un )::try_inner_one o );
或
void func( const decltype( try_main::un )::try_inner_one &o );
我正在尝试使用 g++ 执行以下代码并出现类型不完整的错误
#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;
}
错误:
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);
以上代码已成功使用 gcc 进行编译
此错误的原因是什么以及如何解决此问题
谢谢
C 和 C++ 具有不同的作用域规则。 C++ 中类型的全名不是 struct try_inner_one
,因为类型定义嵌套在 try_main
.1
如果您想编写在 C 和 C++ 中同样有效的代码,请将类型定义拉到顶层:
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 这种类型的完全限定名不能在 C++ 中拼写,因为它嵌套在里面的类型是 unnamed。您可以为联合类型命名,这样您就可以在 C++ 中拼写 try_inner_one
的完全限定名称。但是,该名称不是合法的 C 代码,因为 C 没有范围解析运算符。
如果您想保留嵌套类型定义,您可以为联合命名(在下文中,union_name
)并执行以下操作以保持代码为 C 和 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);
}
What is the reason for this error
原因是 try_inner_one
嵌套在 try_main
中嵌套的联合中,无法通过 C++ 中该联合之外的上下文中的非限定名称查找找到(与 C 不同)。
how to fix this
您可以在 C++ 中使用限定名称:
void func(decltype(try_main::un)::try_inner_one o){
如果你给工会起个名字就可以简化:
union u { // note the name
struct try_inner_one{
void func(try_main::u::try_inner_one o){
一个 cross-language 兼容的解决方案是定义彼此之外的结构,如 Kondrad Rudolph 的回答中所述。
一句警告:C++ 在如何访问联合体的非活动成员方面比 C 更严格。
看来您正在将程序编译为 C++ 程序。在这种情况下,结构 try_main
中的每个声明都具有此结构的范围。
所以你需要像这样声明函数
void func( decltype( try_main::un )::try_inner_one o );
或
void func( const decltype( try_main::un )::try_inner_one &o );