2016-07-17 4 views
-3

誰かが私に説明することができます。なぜこのコードをコンパイルするのが違う動作をするのですか?たとえば、gccには無限ループがありますが、clangは期待通りに動作します。gccとclangをコンパイルする別の結果

私はこのコードをもっと醜いと知っています。数年前に書きましたが、なぜマシンを切り替えるのが簡単なコードにこのような影響を与えているのか疑問に思っています。少なくとも、スタック、ヒープ、何もない。非常に少なくとも

#include <stdio.h> 
main() 
{ 
    int a,b,state,nl,i,temp1,temp2; 
    int words[10]; 
    nl = temp1 = 0; 
    for(i = 0 ; i < 10 ; i++) 
     words[i] = 0; 
    while((a = getchar()) != EOF) 
    { 
     nl++; 
     if(a == ' ' || a == '\t' || a == '\n') 
     { 
      words[nl-2]++; 
      nl = 0; 
     } 
    } 
    for(b=0; b < 10; b++) 
     printf("%d",words[b]); 
    printf("\n"); 
    for(b = 1 ; b <= 10 ; b++) 
     printf("%d",b); 
    printf("\n"); 
    for(b = 0 ; b <= 10 ; b++) 
     if(words[b]>temp1) 
      temp1=words[b]; 
    //printf("%d\n", temp1); 
    for(; temp1 > 0 ; temp1--) 
    { 
     for(i= 0 ; i <= 10 ; ++i) 
     { 
      if(words[i]>0) 
      { 
       // temp2 = i; 
       // for(; temp2 > 0; temp2--) 
       // printf(" "); 
       printf("#"); 
       words[i]--; 
      } 
      else 
       printf(" "); 
     } 
     printf("\n"); 
    } 
} 
+0

このコードにはどのようなインプットがありますか? –

+0

@AndrewL。 'int'をスプーフィングすると何も変わらないので、あなたのコメントはこの問題の範囲外です。もっと正確に言えば、コードは文字通り悪いと言いました。 – kAldown

+0

@BillLynch './a.out kAldown

答えて

4

nl == 1未定義の動作を引き起こすことになるとき

  • words[nl-2]++;を呼び出すことができます。
  • temp1=words[b];は、範囲外の配列にアクセスしているb == 10が呼び出されたときに呼び出すことができます。
  • if(words[b]>temp1) は、範囲外の配列にアクセスしているときに呼び出されます。
  • if(words[i]>0)は、範囲外の配列にアクセスするi == 10が呼び出されたときに呼び出されます。
  • words[i]--;は、境界外の配列にアクセスしているi == 10のときに呼び出すことができます。

一般に、未定義の挙動が与えられると、異なるコンパイラが異なる方法でフォールオーバーされます。

+0

間違っていると私を修正します:' clang'は 'gcc'よりも失敗コードを処理するのに耐性があります'clang'が定義されていない動作につながるコードを生成する可能性がある場合は、安全ですか? – kAldown

+1

@kAldown:彼らは単に失敗するだけです。私はどのコンパイラでもこのコードを信頼しません。 –

関連する問題