5

定義なしのマクロ関数の使用/適用性は何ですか?

#ifndef __SYSCALL
#define __SYSCALL(a, b)
#endif

このマクロはLinuxシステムのヘッダーファイルにあります/usr/include/asm/msr.h

次のようなマクロにも気づきました。

#define _M(x) x

そして、コードを統一するために私が考えることができるこの種のマクロを定義した唯一の理由。#define SOMETHING(1 << 0)のように。この種のマクロの他の隠された(より良い)使用法はありますか?

例を挙げた回答は非常に役立ちます。また、誰かが私にこれについて読むためのテキスト/リンクを提供できますか?

4

5 に答える 5

13

この形式のマクロの最も一般的なケースの1つ:

#define _M(x) x

これは、現在普及しているANSI C方言よりも前のCの元のK&R方言のみをサポートするコンパイラに下位互換性を提供することです。言語の元のK&R方言では、関数を宣言するときに関数の引数が指定されていませんでした。1989年、ANSIは言語を標準化し、引数のタイプの数を宣言する関数プロトタイプを含む多くの改良を取り入れました。

int f(int x, double y); /* ANSI C. K&R compilers would not accept this */

int f(); /* Function declared in the original K&R dialect */

Cの元のK&R方言をサポートするコンパイラは最近ではまれ(または消滅)ですが、両方の種類のコンパイラをサポートする必要があるときに多くのソフトウェアが作成され、マクロは両方をサポートする簡単な方法を提供しました。この下位互換性を提供するヘッダーはまだたくさんあります。

K&Rコンパイラに下位互換性を提供するために、多くのヘッダーファイルには次のものがあります。

#if ANSI_PROTOTYPES
#  define _P(x) x
#else
#  define _P(x) ()
#endif

...

int f _P((int x, double y));

定義が正しく設定されている場合ANSI_PROTOTYPES(ユーザーまたは以前のロジックのいずれかによって#ifdef)、目的の動作が得られます。

  • ANSI_PROTOTYPESが定義されている場合、定義はに展開されint f(int x, double y)ます。
  • ANSI_PROTOTYPESが定義されていない場合、定義は次のように展開されます。int f()
于 2013-03-06T21:34:09.537 に答える
4

これは、前処理を何も行わないようにすることでマクロを無効にする条件式でよく使用されます。例(簡略化):

#ifdef DEBUG
#define ASSERT(x) if(!(x)) { abort(); }
#else
#define ASSERT(x) /* nothing */
#endif
于 2013-03-06T19:21:34.180 に答える
3

私の質問のフォローアップです。

良い答えが得られました。しかし、定義のないマクロが役立つ、より役立つ例をいくつか追加しています。将来役立つことがわかります。

(1) : C ライブラリに THROW が表示されるのはなぜですか?
C と C++ の間でヘッダー ファイルを共有するために使用します。マクロ名は_THROW(x)

#ifdef __cplusplus
    #define __THROW(x) throw(x)
#else
    #define __THROW(x)
#endif  

(2) 関数パラメーターが使用されていない場合の警告を排除する:
この使用法は c++ 用です。Cでは、引数が少なすぎるとエラーが発生しますが、C ++ではエラーなしで動作します:(リンクされたコードパッド)

#define UNUSED(x)
int value = 0;
int foo(int UNUSED(value))
{
    return 42;
}
int main(){
   foo(value);
}

このために、質問にc++タグを追加しました

さらに、
(3):の使用法#define _M(x) xは次のとおりです。コードを一様に並べるためだけです。

/* Signed.  */
 # define INT8_C(c)      c
 # define INT16_C(c)     c
 # define INT32_C(c)     c
 # if __WORDSIZE == 64
 #  define INT64_C(c)    c ## L
 # else
 #  define INT64_C(c)    c ## LL
 # endif

ファイルは次のとおりです。/usr/include/stdint.h

于 2013-03-10T18:48:42.043 に答える
1

これは、そのマクロを使用するコードが条件付きで前処理されて何もなくなることを意味します。

簡単な例として、デバッグコード、ロギング、またはアサーションを検討してください。

于 2013-03-06T19:20:51.203 に答える
1

これはおそらくデバッグ マクロまたはプラットフォーム マクロです。たとえば、INT3 に接続されたデバッガーがあるとします。デバッグ中にこれが発生する可能性があります

 #define debug() INT3()

次に、安全のために、これを本番コードに追加します(それらをすべて削除したことを確認するため)

 #define debug()

これは似たようなものに見えます

一部のシステムでは、このコードが呼び出しを行う必要がある場合があります。たとえば、特定の CPU アーキテクチャや OS などです。しかし、あなたのシステムでは、それはノーオペレーションです。

于 2013-03-06T19:28:48.977 に答える