2012-05-01 13 views
1

バイナリ検索ツリーの挿入機能がありますが、なぜそのエラーが表示されているのかわかりません。たとえ私がFALSEを返しても、関数が終了する直前にもそれが起こります。どんな助けもありがとうございます。警告:コントロールは非void関数の終了に達します。 Cバイナリ検索ツリー

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 
+2

'return'文にヒットしないパスがコード内にあります。 –

+3

少なくとも、コンパイラは存在しないことを証明できません。 –

+0

"返り値をFALSEにしても、関数が終了する直前にもそれが起こります。" 'return FALSE;'をどこに置くことができますか? 'while'ループの後に置くと、診断は間違っています。しかし、コンパイラがそのようなことを間違ったものにしてしまうという誤ってwhileループの中に入れた可能性が高くなります。 –

答えて

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()ループは、内部にreturn経由除き終了しないことを決定します。その場合には、whileの後で常に失敗するアサーションを追加することができます。また、をfor (;;)に変更することも考えられます。これは、returnまたはbreakというステートメントが内部にあるため(これはおそらくassert(cursor != NULL)が上部にあるため)終了するループであることを「文書化」していると考えられます。

関数の終了直前にreturn FALSE;を置くと、警告が消えます。

+0

関連するノートでは、C#のリターンパスの処理についての質問はhttp://stackoverflow.com/q/10114258/12711を参照してください。 C#の仕様では、関数のリターンパスをある程度チェックする必要があります。コンパイラがチェックする方法の制限があります。 C#では、末尾に 'return'がない質問に似た関数は、警告ではなくエラーになります。 –

+0

ありがとう、これは理にかなっています。私は新しいコンパイラを使用していて、警告について心配していました。 –