3

標準ライブラリは、テンプレート型の要件を破ったり、誤った関数引数を与えたり、その他の契約違反を行ったりした場合、習慣的に未定義の動作を許可します。ユーザーライブラリでこれを許可することは良い習慣と考えられていますか? そうするのが公正なのはいつですか?

operator[]コンテナーの を作成することを検討してください。

template <typename t>
T& container<T>::operator[](int i)
{
  return internal_array[i];
}

iの境界外のインデックスの場合internal_array、未定義の動作にヒットします。これが発生することを許可する必要がありますか、それとも境界チェックを行って例外をスローする必要がありますか?

もう 1 つの例は、int引数を取りますが、制限されたドメインのみを許可する関数です。

int foo(int x)
{
  if (x > 0 && x <= 10) {
    return x;
  }
}

xドメイン内にない場合、実行はreturnステートメントなしで関数の最後に到達します。これにより、未定義の動作が発生します。

ライブラリ開発者は、これを許可するかどうかを気の毒に思うべきでしょうか?

4

2 に答える 2

3

意図的に未定義の動作を引き起こすのはいつですか?

ライブラリ実装者の観点からこれを尋ねていると仮定すると、特定の関数の前提条件に準拠しないと未定義の動作が発生し、クライアントがそれらの前提条件を破ることをクライアントに警告するときはいつでも。

C++11 標準ライブラリでは、そのような関数が多数定義されています。シーケンス コレクションの添字演算子について考えてみてください。

一方、アプリケーション プログラマーの観点からこれを尋ねている場合、コンパイラの文書化された拡張機能やその他の拡張機能に依存する移植性のないコードを作成している場合を除き、答えはもちろん「絶対にありません」です。オペレーティング システムの機能 (ただし、まだ「C++ を話している」かどうかは議論の余地があります)。

ライブラリ開発者は、これを許可するかどうかを気の毒に思うべきでしょうか?

もしそうなら、Mr. ステパノフは今では恐ろしいと感じているはずです。いいえ、それは悪くありません。ライブラリが最大の効率性と最大の安全性のために設計されているかどうかに依存します-中間に多くのニュアンスがあります.

于 2013-02-13T23:03:47.490 に答える
1

それはすべてドキュメンテーションに要約されます。

[]直感的には、境界チェックを行うことは期待できませんがat、コンテナに例外をスローするメソッドを提供することもできます (ええ、ちょうどstd. もちろん、例外をスローすることもできますが、この動作を文書化してください。

2 つ目はフェアプレイであり、関数が不適切な引数で呼び出された場合の動作が未定義であることを明確に文書化しており、そうする正当な理由 (赤) がある場合に限ります。パフォーマンスが重要なライブラリを設計している場合、入力をチェックするオーバーヘッドは望ましくありません。そうでない場合は、例外をスローします。

于 2013-02-13T23:06:28.117 に答える