【问题标题】:GCC: array type has incomplete element type?GCC:数组类型的元素类型不完整?
【发布时间】:2010-02-16 16:44:34
【问题描述】:

当我尝试编译时,GCC 给了我一个“数组类型的元素类型不完整”的错误消息:

typedef struct _node node;
struct _node{
 int foo;
 node (*children)[2];
 int bar;
};

在内存中结构应该是这样的

0x345345000000 foo
0x345345000004 pointer to 1. child node
0x345345000008 pointer to 2. child node
0x34534500000C bar

【问题讨论】:

    标签: arrays gcc pointers struct typedef


    【解决方案1】:

    这是因为 C 类型表达式的工作方式相反。

    这个:

    node (*children)[2];
    

    如下所示:children 的内容,当取消引用时(* 应用于它们),产生可以应用数组运算符 [] 的东西,产生 node。这意味着children 是一个指向两个node 的数组的指针。但是,您不想要一个指向数组的指针,您想要一个包含两个指针的数组。为此,您应该这样放置括号:

    node *(children[2]);
    

    然后读取为:children 的内容是一个包含两个值的数组;在其中一个上应用* 会产生node。这就是你想要的:一个由两个指向 node 的指针组成的数组。请注意,这相当于:

    node *children[2];
    

    因为在 C 语法中,当涉及到类型表达式时,[] 运算符优先于 * 运算符。

    在您的初始版本中,C 编译器会抱怨,因为在它读取声明时,它不知道 node 的大小(结构定义尚未完成),因此难以想象键入“两个node 的数组”。这是问题的一个相当间接的症状。

    旁注:您应避免在代码中使用_node 或任何其他以下划线开头的标识符。这些标识符是为“实现”保留的。在实践中,系统标头可能会使用它们,并且冲突可能会被证明是有害的。就个人而言,我倾向于在 end 处添加下划线,例如:typedef struct node_ node;

    【讨论】:

    • 我很困惑你为什么要使用下划线。 typedef struct node node; 完全有效,如果您愿意/需要,可以使用 struct node
    • @R..:我遇到过不接受 typedef struct node node; 的旧 C 编译器。此外,在 C++(不是 C)中,结构标记和类型名称的命名空间并不是完全不相交的;所以我习惯于对结构标签和类型名称使用不同的标识符,因此是最后的下划线。我发现它对我的大脑也有帮助:对于我老化的神经元来说,无论给定的标识符是结构标记还是类型定义的名称,它都变得更加明显。
    • 我猜那些编译器也缺少void 指针。至于 C++,struct 会自动创建一个类型,但该语言允许冗余类型定义,typedef struct foo foo; 是一个非常有用的特例。
    【解决方案2】:

    而不是这个:

     node (*children)[2];
    

    使用这个:

     struct _node* children[2];
    

    【讨论】:

    • 如果我在第 4 行将“node”替换为“struct _node”,则它不起作用。是这个意思吗?
    • 实际上是它的“node* children[2];”,但谢谢。当我卸下括号时它起作用了。 ...该死的指针!
    猜你喜欢
    • 2012-04-17
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多