0

次のようにマクロ展開を設定したとします...

#define WARN_START @"DANGER"
#define WARN_RESET @"THE COAST IS CLEAR"
#define WARN(x) WARN_START x WARN_RESET

INPUT WARN(@"*** Your boss is coming. ***")

OUTPUTDANGER *** Your boss is coming. *** THE COAST IS CLEAR ✅</p>

関数があるとしましょう…</p>

NSString * WhosComing(void){ return @"*** Some fool. ***"; }

そのような関数の結果を、最初に変数に代入せずにマクロに渡すにはどうすればよいですか。

WARN(WhosComing())

ERRORexpected ')'

私は余分な括弧をいじりました、つまり

#define WARN((x))…。または...WARN_START (x) WARN_RESETしかし...</p>

ERRORinvalid operands to binary expressionなど

同様に、cuntion をポインターまたは何かとして渡そうとします。つまりWARN(&WhosComing())、無駄です。これは可能/簡単だと確信しています...しかし、私はCSの学位を持っていないので、方法を学んだことはありません..誰かにとって簡単な答えはありますか?

4

2 に答える 2

3

マクロで試みていることはできません。コンパイル中に隣接する文字列リテラルが連結されるのは C 言語 (したがって、Objective-C、C++) の機能であり、Objective-C ではリテラルが含まれるように拡張されていNSStringます。

マクロは次のように展開されます。

@"DANGER" @"*** Your boss is coming. ***" @"THE COAST IS CLEAR"

次に、コンパイラはこれら 3 つのリテラルを 1 つに連結します。

ただし、関数を渡すと、次のようになります。

@"DANGER" WhosComing() @"THE COAST IS CLEAR"

これは無効なコードです。

さまざまな解決策があります。関数呼び出しのコストが本当に心配な場合は、実際の関数をインライン化して使用できます。

NS_INLINE NSString *WARN(NSString *msg)
{
   return [NSString stringWithFormat:@"%@%@%@", WARN_START, msg, WARN_RESET];
}
于 2013-04-01T17:58:11.090 に答える
2

関数の結果は実行されるまで存在しないため、コンパイル時に関数の結果を挿入することはできません。しかし、次のようなことができます:

#define WARN(x) [NSString stringWithFormat:@"%@ %@ %@", WARN_START, (x), WARN_RESET]

しかし、それは関数に勝るものはありませんね。マクロへの引数がリテラル文字列の場合は、好きなように記述できます。しかし、引数の値はコンパイル時にさえわからないため、マクロ展開段階でできることはあまりないため、実行時に必要な値を生成する式を発行することがほとんど唯一のオプションです.

于 2013-04-01T17:52:34.047 に答える