【问题标题】:Struct doesn't have a field error message in c结构在c中没有字段错误消息
【发布时间】:2018-03-09 17:02:21
【问题描述】:

我正在尝试编写二叉搜索树,但是我的 Clion IDE 在各个地方都给我这个错误:Struct TreeNode doesn't have a field 'balance'。 我选择了“平衡”作为示例,但这发生在结构中的每个字段上。 我的整个头文件如下:

#define CARD_SIZE 15

typedef struct TreeNode *node_ptr;

typedef struct TreeNode{
    char card[CARD_SIZE];
    int balance;
    node_ptr left;
    node_ptr right;
    node_ptr parent;
}Node;

还有一个发生错误的例子是:

bool updateSearch(int balance, char *card) {
    node_ptr node = searchNode(card,tree.root);
    if(node){
        node->balance += balance; //Right here
        return true;
    }
    return false;
}

什么可能导致这个问题?

【问题讨论】:

  • 你确定第二个sn-p中的node_ptr和第一个一样吗? 'node_ptr' 非常通用,很容易被重新定义。
  • @PaulFloyd 是的,这是唯一的 node_ptr 定义。
  • 我试图重现。 (我必须添加一些东西以使其成为 C 中的 minimal reproducible example。)最后,我得到了它,直到出现链接错误。因此,没有编译问题了...这里的链接:ideone
  • 我不太确定,但 gcc 6.3 证明了我:booltruefalse 不是 C。(不是标准)你用C++ 编译器?
  • @PaulR 是的,没有分号或任何东西。我已经用我的整个头文件更新了我的帖子。第一个错误(除了从未使用过的警告)是帖子中的错误。

标签: c struct typedef clion


【解决方案1】:

根据 cmets,我们似乎已诊断出问题,@joneleam 确认该解决方法有效。

这不是编译错误,而是静态分析器的限制。在代码 sn-p 中,node_ptr 的定义为 struct TreeNode*struct TreeNode 的定义之前。因此,当编译器看到该声明时,它只知道TreeNode 是某种struct,它甚至可能不一定在同一个翻译单元中定义。当它确实看到struct TreeNode 的定义之后,它无法将其与node_ptr 的定义统一为struct TreeNode*。因此,它不知道struct TreeNodenode_ptr 成员指向什么,即使它指向另一个TreeNode

解决方法是重构为:

#define CARD_SIZE 15

typedef struct TreeNode{
    char card[CARD_SIZE];
    int balance;
    struct TreeNode* left;
    struct TreeNode* right;
    struct TreeNode* parent;
}Node;

typedef struct TreeNode *node_ptr;

也可以,从技术上讲,#define NODE_PTR struct TreeNode*,如果写出来的代码对你来说太丑陋了,但这对我来说更像是一种代码味道。除非开发人员添加对正确代码(例如您的代码)的支持,或者有更好的解决方法,否则您要做出何种权衡取决于您。

【讨论】:

  • 代码完全有效 C. typedef struct TreeNode *node_ptr;struct TreeNode 声明为不完整类型。下面的声明使它成为一个完整的类型。但显然 Clion 的静态分析器无法识别第二个声明完成了第一个声明中声明的类型。我认为这是一个错误,而不仅仅是一个限制,我建议报告它。
  • @KeithThompson 同意这是“正确的代码”(正如我在回答中所说的那样)。有趣的哲学问题是否称其为“错误”。毕竟,艾伦·图灵证明了在任何图灵完备的语言中总会有一些完全有效的程序会混淆任何给定的静态分析器。但我同意这是 CLion 开发人员应该解决的问题。分析器应该能够统一对struct TreeNode 的前向引用及其在struct 块中的使用与完整类型,就像编译器所做的那样。
  • 我不确定图灵与此有什么关系。这只是正确处理 C 源代码的问题。编译器需要这样做;也应该需要第三方分析器来执行此操作。静态分析器无法始终确定某些事情(例如程序是否停止),但根据语言规则的代码正确性并不是其中之一。
  • @KeithThompson 这绝对属于静态分析器可以并且应该能够弄清楚的类别,是的。
猜你喜欢
  • 1970-01-01
  • 2018-06-28
  • 2020-07-17
  • 1970-01-01
  • 1970-01-01
  • 2011-08-24
  • 2013-11-05
  • 1970-01-01
  • 2020-07-03
相关资源
最近更新 更多