18

さまざまな経験レベルの開発者からコミットを受け取る、適度なサイズのCコードベースがいくつかあります。assert()あまり訓練されていないプログラマーの中には、アサーションが無効になっているバグを引き起こす副作用のあるステートメントをコミットする人もいます。例えば

assert(function_that_should_always_be_called());

すでに独自のassert()実装を使用していますが、NDEBUG定義された式を評価すると、許容できないパフォーマンスの低下が発生します。これらのコンパイル時の警告/エラーをトリガーするGCC拡張機能または渡すことができるフラグはありますか?十分に単純な制御フローを使用すると、GCCは純粋関数のみを呼び出していると判断できるはずです。

4

4 に答える 4

3

十分に単純な制御フローを使用すると、純粋な関数のみを呼び出していることを GCC が判断できるはずです。

そして、それが十分に単純な制御フローでない場合、それが純粋かどうかをどうやって知るのでしょうか?


このようなものがおそらくあなたの最善の策です:

#ifdef NDEBUG
#define assert(s) do { (s); } while(false)
#else
// ...
#endif

を含む関数を含む、いくつかの式がコンパイルされ__attribute__((pure))ます。

最も論理的な解決策は、コードを確認して間違いを修正することです。

于 2012-05-15T02:47:58.220 に答える
1

GCCが純粋な計算を確実に検出できたとしても(停止問題を解決する必要があります)、フラグには、純粋でない計算が引数として自家製のアサートマクロに渡されたことを通知するための追加の魔法の力が必要です。拡張機能も役に立ちませんでした-それは正確に何をすることになっていますか?

あなたの問題の解決策は

  1. 有能な開発者を雇う。
  2. (とりわけ)assertの使用方法について開発者を教育します。
  3. コードレビューを行います。
  4. 成果物のバージョンに対してすべてのテストを実行します-成果物でassertがオフになっている場合、assert(function_that_should_always_be_called())は、テストでキャッチする必要がある露骨なバグであるfunction_that_should_always_be_called()を単に省略することと同じです。
于 2012-05-15T05:13:47.690 に答える