web-dev-qa-db-ja.com

#if defined MACROは#ifdef MACROと同等ですか?

debugverboseの2つのモードが必要なコードがあります。ヘッダーファイルで次のように定義します。

#define verbose TRUE
#define debug TRUE

これまでのところ、私のコードでは、

#if(debug)
  //code
#endif

使用する方が適切ですか

#ifdef debug
  // code
#endif

私はプリプロセッサマクロについて何かを読みましたが、その時点では意味がありませんでした。だから、私は質問があります、#if defined MACRO に相当 #ifdef MACRO?そして、コードの特定のセクションを有効/無効にする方が良いですか?

16
msc
#ifdef MACRO
#if defined (MACRO)

まったく同じことを行います。ただし、定義済み(MACRO)は、#if内で0または1に評価される式であり、他の式と組み合わせることができます。例えば

#if defined (MACRO) && ! defined (MACRO2)
    // Do this
#else
    // Do that
#endif

#ifdefでそれをやってみてください-あなたのコードが本当に不器用にならない限りできません。

18
gnasher729

#if defined(MACRO)#ifdef MACROと同じですが、長くなっています。一方、||または&&を使用して条件を追加できます。

#if MACRO#ifdef MACROに似ていますが、100%ではありません。 MACRO0の場合、#if MACROは負の値になります。MACROを定義し、0ではないようにする必要があります。 #ifdefは、値なしでも定義されているかどうかのみをチェックします(#define MACRO)。

#ifを使用し、値1または0の定義を有効/無効にするようになりました。

#define FLAG_X 1 // or 0

7
i486

いいえ、まったく同等ではありません。 MACROがゼロ以外に評価された場合、_#if MACRO_ブランチがコンパイルされます。一方、MACROdefinedの場合、評価結果に関係なく_#ifdef MACRO_ブランチがコンパイルされます。そう

_#include <stdio.h>

#define VAR_SET_TO_TRUE 1
#define VAR_SET_TO_FALSE 0

int main()
{

#if VAR_SET_TO_TRUE
    printf("#if VAR_SET_TO_TRUE\n");
#endif

#if VAR_SET_TO_FALSE
    printf("#if VAR_SET_TO_FALSE\n");
#endif

#if VAR_UNSET
    printf("#if VAR_UNSET\n");
#endif



#ifdef VAR_SET_TO_TRUE
    printf("#ifdef VAR_SET_TO_TRUE\n");
#endif

#ifdef VAR_SET_TO_FALSE
    printf("#ifdef VAR_SET_TO_FALSE\n");
#endif

#ifdef VAR_UNSET
    printf("#ifdef VAR_UNSET\n");
#endif

}
_

出力されます

_#if VAR_SET_TO_TRUE
#ifdef VAR_SET_TO_TRUE
#ifdef VAR_SET_TO_FALSE
_

printf("#ifdef VAR_SET_TO_FALSE\n");はコンパイルされますが、行printf("#if VAR_SET_TO_FALSE\n");はコンパイルされません。 _VAR_SET_TO_FALSE_はdefinedであるため、最初のコードはコンパイルされます。ただし、その値はfalseです。

7
Dreamer

私があなたの質問を正しく読んでいる場合、タイトルは誤解を招くかもしれませんが、

Is #if MACRO equivalent to #ifdef MACRO?

それらは同等ではありませんが、オンまたはオフのいずれかであるバイナリモードを指定するために両方を使用できます(多くの場合、そうです)。私の意見では、選択は個人的な好みの問題です。

最初のオプションを使用していて、

#define verbose true

または

#define verbose false

そして、どちらかを使用してモードを確認します

#if verbose

または

#if !verbose

実際、trueとfalseはC/C++値であり(またはその可能性がある)、プリプロセッサはCにアクセスできないため、trueではなくTRUEまたは1、falseではなくFALSEまたは0を使用することをお勧めします。/C++値。

とにかく、バイナリモードを指定する他の一般的な方法は、フラグを定義するか、未定義のままにすることです。

#define verbose any thing (including nothing) goes here

または#defineを省略します。

次に、フラグが定義されているかどうかをテストできます。

#ifdef verbose

または同等のもの

#if defined(verbose)

注:この場合、フラグの値をテストするのではなく、定義されているかどうかをテストするだけで済みます。

フラグが未定義であるかどうかをテストすることもできます。

#ifndef verbose

または同等のもの

#if !defined(verbose)
3
Stuart

頭を悩ませれば、違いが出てきます。しかし、それはあいまいであり、未定義の動作を含んでいるため、コードがISO Cに厳密に準拠しているかどうかだけを気にしても問題はありません。

以前に#if defined ...マクロが処理されていた場合、#define defined ...フォームは異なる動作をする可能性があります。 ISO C99標準では、#ifおよび#Elifディレクティブに関して、次のように記述されています。

評価の前に、通常のテキストと同様に、制御定数式となる前処理トークンのリスト内のマクロ呼び出しが置き換えられます(定義された単項演算子によって変更されたマクロ名を除く)。

defined単項演算子を認識し、マクロとして扱われないように保護する必要はありません。これは、「willが...式になる前処理トークン」の1つにすぎません。 defined演算子は、この引数を展開から保護する目的でのみこの段階で認識されます。

マクロとしてのdefineの定義がそのまま許可され、definedの出現がその後置き換えられた場合(#if前処理ディレクティブの引数を含む)、したがって#if defined、ただし#ifdefには影響しません。

おそらく、この言語のこの領域は、C99以降に引き締められました。

2
Kaz