5

私は非常に基本的なクラスを持っており、それをBasicと名付け、より大きなプロジェクトの他のほとんどすべてのファイルで使用されています。場合によっては、デバッグ出力が必要ですが、リリースモードでは、これを有効にせず、NOOPにする必要があります。

現在、ヘッダーには、設定に応じてマクロのオンとオフを切り替える定義があります。したがって、スイッチをオフにすると、これは間違いなくNOOPになります。次のコードがある場合、コンパイラー(MSVS / gcc)が関数呼び出しを最適化できるので、これもNOOPになるのではないかと思います。(そうすることで、スイッチは.cppにある可能性があり、スイッチングははるかに高速になり、コンパイル/リンクの時間的になります)。

--Header--
void printDebug(const Basic* p);

class Basic {
   Basic() {
      simpleSetupCode;

      // this should be a NOOP in release, 
      // but constructor could be inlined
      printDebug(this);
   }
};
--Source--
// PRINT_DEBUG defined somewhere else or here
#if PRINT_DEBUG
void printDebug(const Basic* p) {
   // Lengthy debug print
}
#else
void printDebug(const Basic* p) {}
#endif
4

5 に答える 5

1

コンパイラは、コンパイル時にprintDebug関数の実装を知っている場合、このコードを最適化する可能性があります。printDebugが別のオブジェクトモジュールにある場合、プログラム全体の最適化を使用して、リンカーによってのみ最適化される可能性があります。ただし、これをテストする唯一の方法は、コンパイラで生成されたアセンブリコードを読み取ることです。すでにPRINT_DEBUGマクロがある場合は、TRACEが定義されている方法でそれを拡張できます。

#definePRINT_DEBUG//オプション
#ifdef PRINT_DEBUG
#define PRINT_DEBUG_CALL(p)printDebug(p)
#そうしないと
#define PRINT_DEBUG_CALL(p)
#endif


void printDebug(const Basic * p);

クラスベーシック{
   Basic(){
      simpleSetupCode;

      //これはリリースのNOOPである必要があります。
      //ただし、コンストラクターはインライン化できます
      PRINT_DEBUG_CALL(this);
   }
};
- ソース - 
//PRINT_DEBUGは別の場所またはここで定義されています
#if PRINT_DEBUG
void printDebug(const Basic * p){
   //長いデバッグ出力
}
#endif
于 2010-05-04T08:42:11.440 に答える
1

現在、ほとんどの最適化はコンパイル時に行われます。LLVMなどの一部のコンパイラは、リンク時に最適化できます。これは本当に面白いアイデアです。ご覧になることをお勧めします。

このような最適化を待って、できることは次のとおりです。DEBUGが定義されているかどうかに応じて、次のステートメントを含めることができるマクロを定義します。

#ifdef DEBUG
#define IF_DEBUG (false) {} else
#else
#define IF_DEBUG 
#endif

このように使えます

   Basic() {
      simpleSetupCode;

      // this should be a NOOP in release, 
      // but constructor could be inlined
      IF_DEBUG printDebug(this);
   }

これはすでにはるかに読みやすいです

   Basic() {
      simpleSetupCode;

      // this should be a NOOP in release, 
      // but constructor could be inlined
#if DEBUG
      printDebug(this);
#endif
   }

キーワードのように使用できることに注意してください

IF_DEBUG {
   printDebug(this);
   printDebug(thas);
}
于 2010-05-04T09:15:24.073 に答える
1

このようなすべての質問と同様に、答えは次のとおりです。それが本当に重要な場合は、アプローチを試して、発行されたアセンブリ言語を調べてください。

于 2010-05-04T08:35:53.277 に答える
1
#if PRINT_DEBUG
#define printDebug _real_print_debug
#else
#define printDebug(...)
#endif

このようにして、プリプロセッサはコンパイラに到達する前にすべてのデバッグコードを取り除きます。

于 2010-05-04T09:48:46.177 に答える
0

えーと、プリプロセッサマクロを別の方法で使用してみませんか?

私の頭のてっぺんに、次のようなものがあります。

  #define DEBUG_TRACE(p)
  #ifdef PRINT_DEBUG
    printDebug(p);
  #else
    ;
  #endif
于 2010-05-04T08:48:05.347 に答える