2011-06-24 17 views
2

つの友人は非常に単純な例を示したが、それ自体の最初の要素を押し戻すことができます。コンパイル時にテンプレートの問題を検出する必要があります。この奇妙な行動についてあなたの説明は何ですか?空のベクターは、鉱山の

+3

テンプレートの問題*はコ​​ンパイル時に検出されます。しかし、テンプレートの問題はありません。検出するものは何ですか? –

+0

さらに、コンパイラは、ベクトルが空に初期化され、ベクトルが何であり、v [0]が何を返すべきであるかをどのように知っていますか? –

+1

これは_必ずしもエラーではないので、コンパイラはおそらくこのようなケースを簡単に検出できたとしても、不平を言ってはいけません。たとえば、 'std :: map'では、存在しないインデックスで' operator [] 'を呼び出すことはまったく正当です。これは、新しくデフォルトで構築された要素への参照を返します。コンパイラは間違った使い方について積極的に知ることができないと仮定してはなりません。 – Damon

答えて

2

これは私にとってコンパイル時の問題ではなく、ランタイムの問題のようです。コンパイラは、どのようにベクトルが動くかを知っていますか?

0

これはコンパイル時の問題ではないと言います。コンパイル時に、コンパイラはそのベクトルが空であることを知らないか、または気にしません。

実行時に、ベクトルの最初の要素にアクセスしようとすると例外が発生すると予想されます。

+0

'operator []'は境界チェックをしないので、例外は発生しません。 'v [0]'がヌルポインタを間接参照する可能性があるため、シグナル(例外ではない)が発生する可能性があります。このプログラムは、ゴミの塊をベクターに押し込むかもしれません。これは未定義の動作なので、ここで何も起こることはありません。 –

+0

実際、私が「例外」と言ったとき、私は、メモリアクセスエラーが発生する可能性があることを意味しました。もちろん、メモリがどのように割り当てられるかによって異なります。しかし、ポイントが取られました: – icabod

2

コンパイル 時にテンプレートインスタンス化の問題を検出する必要がありますが、一度インスタンス化すると、インスタンス化の結果は他のクラスまたは関数と同じように正しく動作します( )。表示されている のようなエラーを検出することは一般的に不可能で、結果として実行時に未定義の動作 が発生します。

2

この状況では、未定義の動作がトリガされます。コンパイラは、それを認識する必要はありませんが、試みることはできます。コンパイラがあなたに警告するか、このコードが実行時の問題を引き起こす可能性があります。そうでないと、何もネガティブではないでしょう。

+0

+1 "それはすることができます"。他の答えはすべて、コンパイラが原則としてこのエラーを検出できないことを前提としています*。それは明らかではありません(真実ではありません)。 –

+0

@Konrad:コンパイラはたくさんのことをチェックできました。しかし、どのようにUBのテストを書いて、それを書いていくのか、あなたはどのように優先順位をつけますか? ''以前に変更されていない ''デフォルトコンストラクタ 'を使った 'ローカルベクトル'の' 'operator []'の '' const expression'の '' const式 'のテストはおそらくいくつかのリストの一番下にあります。それほど有用ではありません。 –

+0

@Martin:これはすべて非常にうまくいきます - そしておそらくそれが行われていない理由です。しかし、原理的にはできないと言っているのと同じではありません。例えば、空ベクトルからの読み取りを禁止することは、副作用のないシステム(すなわち、不変ベクトルを用いる)において、概念的に非常に単純である。 –

0

実行時でも、このコードの動作は未定義です。ベクタに誤ってバインドされている場合に、(エラーのフラグを立てる例外の形で)確定的な動作を行うには、vector::operator[]の代わりにvector::at()を使用する必要があります。

関連する問題