括弧で囲みます。
(abs)(whatever);
これにより、マクロが一致しなくなるため、コンパイラは関数バージョンを使用するようになります。
関数のようなマクロは、識別子とそれに続く左括弧を照合することによって機能します(
。関数名自体を括弧で囲んだため、代わりに識別子の後に右の括弧が続き)
、マクロと一致しません。括弧は意味的に透過的ですが、マクロ構文を禁止します。
IIRC、これsplint
を教えてくれたのはCチェッカーでした。Postscript インタープリターを書いているときに、スタックにアクセスするための素敵な短いマクロを作成しました。
#define push(o) (*tos++ = (o))
#define pop() (*--tos)
を含む表現の一部であるトリッキーな部分まで、これは素晴らしかったtos
です。未定義の動作を回避するために、関数のバージョンを作成し、それらをトリッキーなスポットに使用する必要がありました。新しいデザインでは、マクロを完全にスキップしました。
編集:私がこれを学んだのは実際にはCoelocantheの本(Peter Van Der LindenのDeep C Secrets)であり、上記の状況が私が最初にそれを必要とした場所であるというしつこい感じがあります. IIRC の彼の例は、C 実装に準拠した関数とマクロの両方として実装されているputchar
か、頻繁に実装されています。getchar