1. ホーム
  2. c++

[解決済み】C++プログラマーが知っておくべき、一般的な未定義動作とは何ですか?[クローズド]

2022-04-12 19:12:51

質問

C++プログラマーが知っておくべき一般的な未定義の動作にはどのようなものがありますか?

みたいなことを言う。

a[i] = i++;

解決方法は?

ポインタ

  • の再参照 NULL ポインタ
  • サイズゼロの "new" アロケーションによって返されたポインタのデリフェレンシング
  • ライフタイムが終了したオブジェクトへのポインタを使用する(例えば、スタックに割り当てられたオブジェクトや削除されたオブジェクトなど)。
  • まだ確実に初期化されていないポインタのデリファレンス
  • 配列の境界の外(上か下か)に結果を出すポインタ演算を行うこと。
  • 配列の終端を越えた位置でポインタをデリファレンスする。
  • 互換性のない型のオブジェクトへのポインタの変換
  • 使用方法 memcpy オーバーラップするバッファをコピーする .

バッファオーバーフロー

  • 負のオフセット、またはそのオブジェクトのサイズを超えるオフセットでのオブジェクトまたは配列の読み取りまたは書き込み(スタック/ヒープオーバーフロー)。

整数のオーバーフロー

  • 符号付き整数のオーバーフロー
  • 数学的に定義されていない式の評価
  • 負の値による値の左シフト(負の値による右シフトは実装定義されています)
  • 数値のビット数以上の量だけ値をシフトする(例. int64_t i = 1; i <<= 72 は未定義)

型、キャスト、コンスト

  • 数値を、対象の型では表現できない値にキャストする(直接、またはstatic_castを経由して)。
  • 確実に代入される前の自動変数を使用する(例. int i; i++; cout << i; )
  • 以外の型のオブジェクトの値を使用する。 volatile または sig_atomic_t 信号受信時
  • 文字列リテラルやその他の const オブジェクトを、その有効期間中に変更しようとすること
  • 前処理中に幅の狭い文字列リテラルを連結する。

関数とテンプレート

  • 値を返す関数から値を返さない(直接、またはtry-blockからのフローオフ)。
  • 同じエンティティ(クラス、テンプレート、列挙、インライン関数、スタティックメンバ関数など)に対して複数の異なる定義がある。
  • テンプレートのインスタンス化における無限の再帰性
  • 関数が使用すると定義されているパラメータやリンケージと異なるパラメータやリンケージを使用して関数を呼び出すこと。

オーパーツ

  • 静的な保存期間を持つオブジェクトのカスケードデストラクション
  • 一部重複するオブジェクトに割り当てた結果
  • 静的オブジェクトの初期化中に、関数に再帰的に再入力する。
  • オブジェクトのコンストラクタまたはデストラクタから、そのオブジェクトの純粋仮想関数への仮想関数呼び出し
  • 構築されていない、または既に破棄されたオブジェクトの非静的メンバを参照する。

ソースファイルとプリプロセッシング

  • 改行で終わらない、またはバックスラッシュで終わる、空でないソース ファイル(C++11 より前のバージョン)
  • バックスラッシュの後に、文字または文字列定数の指定されたエスケープコードに含まれない文字が続く場合(これはC++11では実装定義されています)。
  • 実装上の制限を超えた場合(ネストされたブロック数、プログラム内の関数数、使用可能なスタックスペース...)。
  • で表現できないプリプロセッサの数値を long int
  • 関数型マクロ定義の左側にある前処理指示文
  • 定義されたトークンを動的に #if 表現

分類されること

  • 静的記憶期間を持つプログラムの破壊時に終了を呼び出すこと