3
#define FREE1(x) do { free(x); x = NULL; } while (0);
#define FREE2(x) { free(x); x = NULL; }

これらのマクロの違いは何ですか?

4

4 に答える 4

12

あなたの質問がdo/whileマクロのトリックに関するものである場合、違いはありません。なぜなら、最初のマクロ定義で明らかにエラーを犯し、トリックの目的を完全に無効にしたからです。;の後にを置きwhole (0)ます。適切な実装では、最初のマクロにafterを絶対に含めないでください。これがトリックの要点です。;while (0)do/while

今、このコードはコンパイルされません

if (condition)
  FREE2(arg);
else
  /* something else */;

このコードもコンパイルされません

do 
  FREE2(arg);
while (condition);

この手法のポイントは、do/whileこのコードをコンパイルすることです。FREE1ただし、前述のエラーのため、マクロでコンパイルされません。

ただし、最初のマクロを正しく定義すると

#define FREE1(x) do { free(x); x = NULL; } while (0)
// No `;` at the end!!!

最初のマクロは、上記のコード サンプルで完全に正常に動作します。これが実際に、do/whileマルチステートメント マクロでこの手法を使用する理由です。つまり、そのようなコンテキストで通常の関数を正しくかつ均一に機能させるためです。

PS補足として、そのようなすべての手法の目的は、複数のステートメントのグループを1つの複合ステートメントに変換することです。特定のケースでは、シーケンスを単一のfree(x); x = NULL;として再実装できます。これにより、複数ステートメントのマクロ手法が不要になります。つまり、これ(free(x), x = NULL)

#define FREE3(x) (free(x), x = NULL)

同様に動作します。しかし、それは個人的な好みの問題です。

于 2012-12-21T16:02:55.697 に答える
5

実際、Cに関しては違いはありません。

その理由は、末尾にセミコロンが含まれているためです。

#define FREE1(x) do { free(x); x = NULL; } while (0);

あなたが通常使用したい理由do...while(0)ここで説明されています、あなたは一般的にそれをif...elseブロックで使用したいということです:

if (...)
    FREE(x);
else
   ...

しかし、上記の使用法とマクロを使用すると、これは次のようになります。

if (...)
   do { free(x); x = NULL; } while (0);;
else
   ...

...と...

if (...)
    { free(x); x = NULL; };
else
    ...

...両方とも不正な形式です。

于 2012-12-21T16:04:20.820 に答える
2

どちらも、C /C++マクロのDo-Whileおよびif-elseステートメントで説明されているセミコロンの問題を修正するための半ば焼きの試みです。

このマクロを定義するためのより良い方法は

#define FREE3(x) do { free(x); x = NULL; } while (0)

(末尾のセミコロンなし。)

于 2012-12-21T16:05:22.043 に答える
0

これ:

#define FREE1(x) do { free(x); x = NULL; } while (0);

一度だけ実行されるため、次と同じです。

#define FREE2(x) { free(x); x = NULL; }

しかし、アセンブリ コードにはさらに分岐があります。最新のコンパイラがおそらくそれを最適化したとしても、生成されるアセンブリ コードでさえ、すべての確率で同じになります。

于 2012-12-21T16:01:09.100 に答える