1

二分探索ツリーの挿入機能がありますが、そのエラーが発生する理由がわかりません。return FALSE; を入れても; 関数が終了する直前でも発生します。どんな助けでも大歓迎です。

boolean insert(NODE **root, Employee e){
NODE *cursor,*temp;
// boolean status;

temp = (NODE *)malloc(sizeof(NODE));
assert(temp != NULL);

temp->element = (Employee *)malloc(sizeof(Employee));
assert(temp -> element != NULL);

*(temp -> element) = e;
temp -> left = NULL;
temp -> right = NULL;

if (*root == NULL) {
    *root = temp;
    return TRUE;
}

// tree is non-empty
cursor = *root;
while (cursor != NULL) {
    if(e.ID < cursor -> element -> ID){
        if(cursor -> left == NULL){
           cursor -> left = temp;
           return TRUE;
        }
        else cursor = cursor -> left;
    }

    //e goes to the right
    else {
        if (e.ID > cursor -> element -> ID){
           if(cursor -> right == NULL){
              cursor -> right = temp;
              return TRUE;
           }                        
           else
              cursor = cursor -> right;
        }
        else { // e is already in the tree
           free(temp -> element);
           free(temp);
           return FALSE;
        }
    }
   }  // while cursor != NULL
 } // insert
4

1 に答える 1

0

関数は実際にすべての可能なパスで何かを返しますが、コンパイラは必ずしもそれを決定できるわけではありません. そのため、この診断はエラーではなく警告です。

以下は、常に を返すことが容易にわかる関数の例ですが、0未処理のリターン パスについて警告しようとする多くのコンパイラは、警告を発行します。

int foo( int x)
{
    while (x >0) {
        --x;
    }
    if (x == 0) return 0;
    while (x < 0) {
        ++x;
    }
    if (x == 0)  return 0;
}

ただし、単純な分析で、すべての制御パスが値を返すと判断できる場合があります。以下は通常、診断を生成しません。

int bar(int x)
{
    if (x == 0)
        return 0;
    else 
        return 1;
}

while()あなたのような複雑な関数では、その中の a 以外ではループが決して終了しないと判断することは、誰でも (コンパイラーまたは人間) 非常に難しい場合がありますreturnwhileそうなると予想される場合は、の後に常に失敗するアサーションを追加することをお勧めします。また、内部のorステートメントが原因でのみ終了するループである「ドキュメント」を変更するwhile (cursor != NULL)ことを検討することもできます(上部に がある可能性があります)。for (;;)returnbreakassert(cursor != NULL)

return FALSE;記録のために、関数の最後の直前にa を置くと、警告が消えます。

于 2012-05-01T14:30:20.447 に答える