7

コードの一部の行を定型コードでラップしたいので、次のようにマクロ引数として複数行のコードを渡すことでラップする必要があります。

#define safeRun(x) if (ValidationOK()) {x} 

int main(int argc, char **argv) {
    safeRun(
        foo();
        bar();
    )
}

どうもありがとう。

4

4 に答える 4

8

書かれているように、あなたのコードはコンマ演算子のファウルを実行します(しかし、前に主張したように、関数の引数リストのコンマは実行しません)。

C99を使用していると仮定すると、マクロ内の可変引数でその問題を回避することもできます。

#define safeRun(...) if (ValidationOK()) {__VA_ARGS__}

int main(int argc, char **argv) {
    safeRun(
        foo(a, b),
        bar(c, d);
    )
}

さて、プリプロセッサに関する限り、マクロにはコンマで区切られた2つの引数がありますが、それらは必要に応じて処理されます。gcc -E出力は次のとおりです。

# 1 "x3.c"
# 1 "<command-line>"
# 1 "x3.c"


int main(int argc, char **argv) {
    if (ValidationOK()) {foo(a, b), bar(c, d);}



}

あなたが提案していることが良い考えであるかどうかは、別の議論です。これらは多かれ少なかれそれを機能させるメカニズムです。

于 2013-01-16T07:24:58.840 に答える
1

この文字を使用して\、マクロ定義内の改行を「エスケープ」します。コード行を含む引数内のコンマをサポートするには、可変個引数のマクロ引数を使用します。(この機能はC99の一部ですが、多くの非準拠コンパイラーにも存在します。)

#define safeRun(...) \
[Validation code]; \
if (ValidationOK()) \
    {__VA_ARGS__} \
[Finishing code]; \
/* bumper line to support last backslash, leave empty! */

バックスラッシュと改行の間に空白を入れることはできないことに注意してください。

標準的な警告:マクロはカプセル化の最もリークの多い形式です。可能であれば、他の構成を使用してください。

于 2013-01-16T07:20:25.367 に答える
1

@Potatoswatterが言うように、バックスラッシュを使用できます。

#define safeRun(x) \
  [Validation code]; \
  if (ValidationOK()) \
      {x} \
  [Finishing code]; \

ただし、次のように使用すると、これが問題になる可能性があります。

if (x)
  safeRun(y);
else
  ...

問題を解決するには:

#define safeRun(x) \
  do { \
      [Validation code]; \
      if (ValidationOK()) \
          {x} \
      [Finishing code]; \
  } while(0);
于 2013-01-16T07:36:14.700 に答える
0

関数のようなマクロは、いくつかの理由で非常に悪いです。これを解決するためのはるかに優れた方法は、実際の関数を使用することです。

start_safe();
  foo();
  bar();
stop_safe();
于 2013-01-16T07:30:21.467 に答える