0

学校では、プリプロセッサステートメントは簡単に混乱する可能性があるとよく教えられました。たとえば、次のような文字列を定義するからです。

#define PI 3.1415926

コード内のあらゆる場所で置換されるため、変数名に文字列が含まれていると、奇妙な置換が発生しますPI

したがって、デバッグするときは、次のアプローチから離れます。

#define _DEBUG
...
#ifdef _DEBUG
    // debug code
#endif
...

しかし、使用する方が「安全」だと考えました。

const static bool DEBUG = true
int main()
{
    ...
    if(DEBUG){ /* debug code*/ }
    ...
}

これはうまく機能しますが、プリプロセッサステートメントのアプローチと比較して、このアプローチの実行時のオーバーヘッドは何でしょうか。プリプロセッサアプローチでは、すべてがコンパイル前に行われるため、実行時のオーバーヘッドは予想されません。

単純なステートメントのオーバーヘッドはほとんど無視できることを私は知っていますが、ifこれは、多数回実行されるいくつかのネストされたループに深く入れられた場合には当てはまりません(小さなものが大きなものになります)。

コンパイラは、これを実行可能ファイルにハードコードし、コンパイル時にデバッグコードをすでに有効または無効にしてDEBUGいるという事実を認識していますか?これを疑うのは、先日、無関係なコードで作業しているときに、コードの一部が廃止されたという警告があったことです。これは、コードを囲む-statementが真になることはないためです(正しく覚えていれば)。const staticif

4

4 に答える 4

3

厳密な保証を与えることは不可能です。フィードしたコードをどう処理するかは、個々のコンパイラ次第です。

ただし、実際のコンパイラはこれを最適化します。これは、存在する最も単純で最も自明な最適化の 1 つであり、最適化を無効にしても、ほとんどのコンパイラはおそらくそれを行うでしょう。

本質的に何のためにコードを生成しても意味がありませんif (true)

したがって、実行時のオーバーヘッドはゼロになるはずです。

于 2012-04-09T13:05:38.803 に答える
3

標準には、コードが実行されないと静的に (コンパイル時に) 判断できる場合、コンパイラがコードの一部を完全に省略できないという規定はありません。

一方、標準には、コンパイラがその最適化を行う必要があることを示すものは何もありません (一般的な場合)。

したがって、コンパイラに十分な情報を提供し、最適化機能をオンにすると、これらの分岐が完全に排除される可能性が高くなります。しかし、それを確認する唯一の方法は、生成されたコードを確認することです。

そのような「些細な」デバッグ対応コードの場合、最新のコンパイラのほとんどは、ほとんどの状況でデッド ブロックを完全に排除します。

于 2012-04-09T13:06:29.503 に答える
1

学校では、定義する文字列が次のようになるため、プリプロセッサステートメントは簡単に混乱する可能性があるとよく教えられました。

#PI 3.1415926 を定義

コード内のあらゆる場所で置換され、変数名に文字列 PI が含まれている場合に奇妙な置換が発生します

いいえ、別のトークン内ではなく、PI単語全体 (トークン) のみを置換します。PIたとえばmyPI、展開しませんPI

于 2012-04-09T14:41:02.503 に答える
0

これは詳細ですが、DEBUG は const bool になっているため、小文字で記述する必要があります。

const static bool debug = true;

大文字の名前は、プリプロセッサ マクロ用に予約されています。

于 2014-09-09T16:54:33.787 に答える