#if 0…#endifブロックは正確には何をしますか?


124

ではC / C ++

#if 0/ #endifブロックの間に置かれたコードはどうなりますか?

#if 0

//Code goes here

#endif

コードは単にスキップされるため、実行されませんか?


17
これは、大量のコードをコメント化したり、コードブロックの包含をテストしたりするために使用される手法です。この機能がない場合、各行の//先頭にプレフィックスを付けるか、セクションをで始めてセクションを/*で終わる必要があり*/ます。後者の手法の問題は、コメントがネストされないため、開発者*/は開始と終了の間をチェックして処理する必要があることです。
トーマスマシューズ

回答:


141

実行されないだけでなく、コンパイルもされません。

#if実際のコンパイル手順の前に評価されるプリプロセッサコマンドです。そのブロック内のコードは、コンパイルされたバイナリには表示されません。

多くの場合、後で再び有効にするためにコードのセグメントを一時的に削除するために使用されます。


1
これは、あらゆる種類のコメントに当てはまります。重要な違いは入れ子です。
Samy Bencherif

73

これは、ブロックをコメントアウトすることと同じですが、重要な違いが1つあります。ネスティングは問題ではありません。このコードを考えてみましょう:

foo();
bar(x, y); /* x must not be NULL */
baz();

コメントアウトしたい場合は、以下を試してみます。

/*
foo();
bar(x, y); /* x must not be NULL */
baz();
*/

Bzzt。構文エラー!どうして?ブロックコメントはネストされないため(SOの構文の強調表示からわかるように)*/、単語 "NULL"の後はコメントを終了し、baz呼び出しはコメント化されず、構文エラーの*/後にbazなります。一方:

#if 0
foo();
bar(x, y); /* x must not be NULL */
baz();
#endif

全体をコメントアウトするように機能します。そして、#if 0sは次のように互いにネストします。

#if 0
pre_foo();
#if 0
foo();
bar(x, y); /* x must not be NULL */
baz();
#endif
quux();
#endif

もちろん、これは少し混乱する可能性があり、適切にコメントしないとメンテナンスの頭痛になる可能性があります。


5
#if内のコードは(コメントではなく)字句的に正しい必要があり、プリプロセッサディレクティブは引き続き有効です(同上)。
jpalecek 2010年

@David:字句的には正しくありませんが、コンパイルは可能です。したがって、コードは字句的に正しい必要はありません。
Dennis Zickefoose

1
@デニス、私foo.c:3: unterminated string or character constantはgccから入手しました、何を使っていますか?
David X

18

それはそのコードを永久にコメントアウトするので、コンパイラーは決してそれをコンパイルしません。

コーダーは後で#ifdefを変更して、必要に応じてそのコードをプログラムでコンパイルすることができます。

コードが存在しないのとまったく同じです。


15

#if 0…#endifブロックは正確には何をしますか?

それは、作者が明らかにバージョン管理システムについて聞いたことがないことを示しています。これにより、可能な限り遠くまで走るように指示されます…


12

私は#elseケースに追加したいと思います:

#if 0
   /* Code here will NOT be complied. */
#else
   /* Code will be compiled. */
#endif


#if 1
   /* Code will be complied. */
#else
   /* Code will NOT be compiled. */
#endif

7

プリプロセッサは#ifを見ると、次のトークンにゼロ以外の値があるかどうかをチェックします。含まれている場合は、コンパイラのコードを保持します。そうでない場合は、そのコードが削除されるため、コンパイラーはそのコードを認識しません。

誰かが#if 0と言った場合、コードをコメントアウトしているため、コンパイルされることはありません。これは、彼らが/ * ... * /を囲んでいるかのように考えることができます。まったく同じではありませんが、効果は同じです。

何が起こったかを詳しく知りたい場合は、よく見ることができます。多くのコンパイラーでは、プリプロセッサーの実行後にファイルを表示できます。たとえば、Visual C ++では、スイッチ/ Pコマンドはプリプロセッサを実行し、結果を.iファイルに書き込みます。


結構です。プリプロセッサは、トークンではなく行ごとに解析します。あなたの説明によると、例えば言うことはできませんが#if WIN32 || __CYGWIN__、これは期待通りに機能します。
ベンフォークト

単純化していました。orがある場合は、いずれかのトークンがゼロでないかどうかをチェックします。同様に、があり、両方がゼロでないかどうかをチェックします。
Steve Rowe

3

aで始まる行#は、プリプロセッサディレクティブです。 #if 0 [...] #endifブロックはコンパイラに到達せず、マシンコードを生成しません。

ソースファイルを使用してプリプロセッサで何が起こるかを示すことができますifdef.cxx

#if 0
This code will not be compiled
#else
int i = 0;
#endif

実行gcc -E ifdef.cxxすると、何がコンパイルされるかが表示されます。

このメカニズムを使用して、開発サイクル中にコードのブロックがコンパイルされないようにすることもできますが、コードに粗末が追加されて読みやすさが低下するため、ソース管理にチェックインしたくない場合があります。コメント化されているコードの履歴部分である場合は、削除する必要があります。ソース管理には履歴が含まれていますよね?

また、答えはCC ++の両方で同じかもしれませんが、C / C ++と呼ばれる言語はなく、そのような言語を参照するのは良い習慣ではありません。


4
「CまたはC ++」の省略形としてC / C ++と言うことの何が問題になっていますか?「C / C ++」という言語があると戸惑う人がいると正直に思いますか?
クリストファーバーバー、

1
@Chris:「C / C ++でXを実行するにはどうすればよいですか?」これは無意味な質問です。あなたはどちらかでコーディングしていて、まだ選択していない場合は、そのことを明示する必要があります。だから、はい、人々は「C / C ++」と呼ばれる言語があることについて混乱しています
Dennis Zickefoose

1
なんて無意味な発言でしょう!CとC ++の両方に関連する質問が何千とあります。これは質問をするためのサイトであることを忘れないでください。一般的な質問をしているからといって、使用している言語がわからないわけではありません。この質問のようにそうであると疑われる場合、CまたはC ++を指定することはどのように役立ちますか?CまたはC ++のいずれかに当てはまる可能性のあるすべての質問を2度尋ねると役立つと思いますか?
Christopher Barber、

@クリストファー:そのとおりです。答えがC、C ++、およびObjective-C(これはその1つです)と同様に関連している多くの質問があります。Stack Overflowには、質問が属する言語を示すための便利なタグ付けシステムがあります。@Dennisが言及しているように、SO(および他のプログラミングフォーラム[フォーラム?])には、Cと他のC派生言語の区別について混乱している人が(あまりにも)います。適切な言語で質問に答えるのは難しいです。
Johnsyweb、

2

かなり

int main(void)
{
   #if 0
     the apostrophe ' causes a warning
   #endif
   return 0;
}

gcc 4.2.4で「tc:4:19:警告:終了文字 'がありません」が表示されます


2
この警告は、コンパイラーではなく、プリプロセッサーによって生成されます。コンパイラは次のものだけを取得します。#1 "tc"#1 "<built-in>"#1 "<command-line>"#1 "tc" int main(void){return 0; }
Johnsyweb、

0

これは安価なコメントアウト方法ですが、デバッグの可能性があると思います。たとえば、値をファイルに出力するビルドがあるとします。最終バージョンではそれを望まないので、#if 0 ... #endifを使用できます。

また、デバッグ目的でそれを行うより良い方法は次のようにすることだと思います:

#ifdef DEBUG
// output to file
#endif

あなたはそのようなことをすることができます、そしてそれはより理にかなっているかもしれません、そしてあなたがしなければならないすべては結果を見るためにDEBUGを定義することです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.