2012-06-25 20 views
8

私はシーケンスポイントはどこから来ますか?

++a = a++; 

ような何かを書くことだけでなく、読めないだけでなく、C/C++シーケンスポイントに違反していることを知っています。

これらの制限はどこから発生しますか?バグとして見つけられる前に、それらの「問題」をどのように見ることができますか?

+0

それでも、それは言語設計の限界か、むしろどの言語にも共通のマシン(CPU)リミエーションですか? –

+5

'エラー: 'a'の操作は未定義です[-Werror =シーケンスポイント]' - あ、ありがとう、便利なコンパイラ。 – chris

+1

すべての警告をオンにし、警告をコンパイルして、それらを論理的なエラーとして扱います。これについて心配する必要はありません: '-Werror -Wall -Wextra -ansi -pedantic' –

答えて

8

基本的に各ステートメントの間にはC++ 03のシーケンスポイントがあります。詳細については、SO C++ FAQを参照してください。さらに詳しい情報はC++標準を参照してください.C++ 11の標準シーケンスポイントではの前に、の関係になるように配列されています。

問題を回避するには、各式で多くのことをすることについて賢明にしようとしないでください。

コンパイラのジョブを実行しようとしないでください。コンパイラに任せてください。あなたの仕事は、他の人間が容易に理解できるコード、つまりクリアコードを書くことです。副作用を伴うオペレーターの複数の更新と不必要な使用は、それと互換性がありません。

ヒント:まったく可能な限りconstを振ってください。

これは、読者が考慮しなければならない可能性のある状態の変化を制限します。

+0

答えてくれてありがとう。私はここで多くの答えを「受け入れる」ことができたらいいと思う) –

4

How can one see those 'problems' before finding them as bugs?

プログラムを最も厳密なレベルでコンパイルし、すべての警告の設定をエラーとして指摘できるようにします。ほとんどの主流のコンパイラは、シーケンスポイントによる未定義動作エラーを指摘しています。あなたが使用することができますgccで

:シーケンスポイントの問題を指摘しなければなら

-Wsequence-point 

-Wallを使用すると、デフォルトで有効になります。

もちろん、最も良い方法は、シーケンスポイントの間違った冒険を避ける、より読みやすいコードを作成して書くことです。

+2

@chris: '-Wall'は既述したように、既述の通りです。 –

+0

確かに、私はそれを誤解しました。 – chris

+0

'-Wsequence-point'オプションに+1します。私はそれを知らなかった。 – Nawaz

7

これらはCまたはC++の標準であり、効果的にsequence pointsをリストしています。 いくつかの単純なケースでは、コンパイラは未定義のビヘイビアを呼び出していることを警告できますが、一般的な場合はそうではありません。

しかし、あなたの例のような「面白い」コードを書いているのならば、通常、シーケンスポイントの要件に違反しているだけです。言語標準のように、このようなコード(Javaのような言語)に特定の制約を課すことができますが、大きな利点はなく、特定のタイプの最適化を妨げる潜在的な欠点です。


1.専門用語はC++ 11に少し変更されましたが、原理はまだ大部分は同じですが、私は思います。

+0

答えをありがとう。私はここで多くの答えを「受け入れる」ことができればと思います;) –

+0

これについてのC++ 98とC++ 11の違いについて私は少し前に質問しました:http://stackoverflow.com/a/10655884/365496 – bames53

関連する問題