2012-05-16 9 views
29

私はそれゆえ、私はコードの操作は未定義ですか?

trackTail[nodeNumber-1] = ++trackTail[nodeNumber-1] % 10; 

すべてがで完璧に動作している理由は、次のコード

FRAME frameArray[5][10]; // Create the array of frames 
int trackBufferFull[5] = {0, 0, 0, 0, 0};// Keeps track of how full the buffer for each node is 
int trackFront[5] = {0, 0, 0, 0, 0}; // Array to keep track of which is the front of the array 
int trackTail[5] = {0, 0, 0, 0, 0}; 


// Function to add to the array (CHANGE int frame) 
void addFrame (int nodeNumber, FRAME frame) 
{ 
    //Calc tail 
    int tail = trackTail[nodeNumber-1]; 

    // Calc frames in buffer 
    int framesinBuffer = trackBufferFull[nodeNumber-1]; 

    if (framesinBuffer == 10) 
    { 
     printf("Buffer is full\n"); 
    } 
    else 
    { 

     // Add frame to frameArray 
     frameArray[nodeNumber-1][tail] = frame; 
     printf("\nAdded a frame in node: %i to the buffer\n", nodeNumber); 

     // Increment the count 
     trackBufferFull[nodeNumber-1]++; 
     trackTail[nodeNumber-1] = ++trackTail[nodeNumber-1] % 10; 


    } 
} 

IはframeArrayに使用するアレイは、長さ10のラップアラウンド/環状アレイである持っていますただし、スタンドアロンのファイル、大きなファイルの内部で実行したときに、私は次のようにコンパイルエラーを取得:

$ cnet GARETH -m 30 
compiling gareth.c 
gareth.c: In function ‘addFrame’: 
gareth.c:77:27: error: operation on ‘trackTail[nodeNumber + -0x00000000000000001]’ may be undefined [-Werror=sequence-point] 
gareth.c: In function ‘removeFirstFrame’: 
gareth.c:98:28: error: operation on ‘trackFront[nodeNumber + -0x00000000000000001]’ may be undefined [-Werror=sequence-point] 
gareth.c:105:1: error: control reaches end of non-void function [-Werror=return-type] 
cc1: all warnings being treated as errors 

ライン77はラインです

trackTail[nodeNumber-1] = ++trackTail[nodeNumber-1] % 10; 

ヘルプ。あなたはシーケンスポイント間のtrackTail[nodeNumber - 1]を変更している http://i.imgur.com/wyO5a.png

+1

http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points - あなたは_lucky_コンパイラがあなたに警告します。 – Mat

+1

ほとんど発生しない質問。 +1。 –

答えて

45

ライン77は

trackTail[nodeNumber-1] = ++trackTail[nodeNumber-1] % 10; 

ラインであるあなたはsequence points間で二回trackTail[nodeNumber-1]を変更します割り当て。

これはundefined behaviourです。

救済文を言い換えることですので、のような例えば:

trackTail[nodeNumber-1] = (trackTail[nodeNumber-1] + 1) % 10; 

かそこらのような:

trackTail[nodeNumber-1]++; 
trackTail[nodeNumber-1] %= 10; 
+0

ありがとう、最初に正しく解決しました。私は今すぐ寝ることができます:) H @ CO3も持っていますが、直後に '(trackTail [nodeNumber-1] + 1)%10; 'を使いました。 – gbhall

5

行番号とコードと並んでエラー側を表示するには、私はに画像をアップロードしました。割り当てようとしているのと同じです。

i = ++i; 

これも未定義の動作です。

このような何かにあなたのコードを変更し

:一度++を通じて、一度通過:

trackTail[nodeNumber - 1] = (trackTail[nodeNumber - 1] + 1) % 10; 
+0

あなたの提案した解決策は私に間違って見えます。 1行に 'trackTail [nodeNumer - 1]'を1つ追加してから、次の行で++を使って*をもう一度インクリメントします。 – sepp2k

+0

Nope。 tracktail [nodeNumber + 1]に1を加えることは、増分された値を割り当てません。だからこそ養殖が必要です。OPはモジュロが* plus one *の値で実行されることを望んでおり、同時にその配列要素の値を増やしたいと考えています。 –

+1

何ですか?右側のオペランドがインクリメントされた値を代入演算子として持つため、インクリメントされた値(モジュロ10)は 'trackTail [nodeNumer-1]'に代入されます。 'trackTail [nodeNumber - 1] =(trackTail [nodeNumber - 1] + 1)%10;'を実行した後、 'trackTail [nodeNumber - 1]'の値は前の値+ 1モジュロ10になります。後続の行では、元の値に2を加えたものになります(元の値が8でない限り10を法とします。この場合は10になります)。 – sepp2k

4
trackTail[nodeNumber-1] = ++trackTail[nodeNumber-1] % 10; 

うん、それはエラーメッセージが言う同じように未定義の動作です。間にシーケンスポイントがなければ、同じ値を2回変更することはできません。この場合は、trackTail[nodeNumber-1]++で増分することと、=を使用して再割り当てすることの両方を許可されていないことを意味します。

++の代わりに+ 1を使用すると問題なく動作します。

+0

ありがとうございます。 – gbhall

関連する問題