2012-02-28 8 views
2

私は質問の積み重ねを見て、これを見ることができませんでしたが、私はそれがどこかに既にあると確信しています。だから私は謝罪し、これは閉鎖されるかもしれないと思うが、うまくいけば、誰かが私の答えを最初に確認するだろう!C++定義されていない動作かどうか? (もう一度)

は、私はそれを考えに修正アム:

while (--len > -1 && ptr = str[len]) 

は明確に定義されている動作(未定義ではありませんか!)?私がこれを理解する方法は、& &がシーケンスポイントであり、短絡が働く方法は、最初に--len > -1を評価し、安全でない場合には2番目の部分が起こらないようにすることです。

私はこの思考プロセスで正しいかどうかはわかりませんでした。

+0

このステートメントの前にlenの値があるかどうかによって異なります。 0以上の場合はどうなりますか? ptr = str [len]が評価されます。 – Sid

+0

ええ、良い点。私の状況では危険ではありませんが、最初は悪いとは考えていませんでした。 :) –

答えて

5

このptr = str[len]&&として振る舞いを定義されていますsequence pointであり、あなたがそれを理解する方法は正しいです。 Cでは

[2]やC++、[3]シーケンスポイントは、次の場所で発生します:リンクWikipediaのページから

& &の左右のオペランドの評価の間(論理AND )、|| (論理OR)、およびコンマ演算子を使用します。たとえば、* p ++!= 0 & & * q ++!= 0の式では、qにアクセスしようとすると、副式* p ++!= 0のすべての副作用が完了します。

ただし、--lenのインデックスがstrの範囲を超えないようにはなりません。 str場合にnullで終わるstrあなたが変更される可能性がある:あなたが--len > -1がfalseの場合ptr = str[len]が実行されていないと考えるのは正しい

while (--len > -1 && len < strlen(str) && ptr = str[len]) 
+0

非常に感謝:) –

+0

@ hmjd:私はループの各実行時に 'strlen'を再計算することを避ける、それは確かに無駄です。もし 'len'が' strlen(str) 'よりも劣っていてそれをデクリメントすると、その事実は変わるべきではありません。もちろん、これは 'str'自体が動かないと仮定しています。 –

1

はい、正しいです。順序は:

  1. len(2)が真と評価された場合len-1
  2. と比較さ
  3. (新しい値)をデクリメントする、
+0

あなたの素早い答えをありがとう;) –

0

(それは未定義の動作がlenがインデックス付きの配列のためには大きすぎるである可能性があり、私はそれがあなたが恐れるものではないと仮定します)。 --lenは、lenが事前にINT_MINである場合、未定義の動作になることがあります(lenがサニエリに初期化されている場合は、やはり可能性がありません)。 = 1 LENのための例では

0
while (--len > -1 && ptr = str[len]) 

(lenがint型である場合)、物事そのように行く:

1) len = len-1=0 
2) ptr = str[0] 

2)if文の最初の部分場合理由でlenの減少です。 はそれがあなたが望むものですか?

しかし、動作は定義され、最初の部分が最初にチェックされます。

0

これは実際には問題ありません。ここでの鍵は、あなたがlenに複数回書いていないということです。

最初にプリデクリメントlenです。次に、デクリメントされた値lenが0以上であることを確認します。次に、ptrstr[len](デクリメントされたlenを使用)を割り当てます。最後に、ptrがNULLでないかどうかを確認し、そうであればwhileループ文を実行します。

lenが符号なし-1であれば、符号なしに昇格し、ループは最初の反復で失敗することになります。さらに、最小値(std::numeric_limits<int>::min())が指定されていない場合は、lenが署名されています。

+0

*ここでの鍵は、あなたがlenに複数回書くことがないことです。*これは必ずしも問題ではありません。 'map [++ i] = i'は' i'に一度だけ書き込みますが、未定義です。 –

関連する問題