私はこのアサーションの例に出くわし、それが何の#
ためにあるのか疑問に思いました。
#define ASSERT( x ) if ( !( x ) ) { \
int *p = NULL; \
DBGPRINTF("Assert failed: [%s]\r\n Halting.", #x); \
*p=1; \
}
私はこのアサーションの例に出くわし、それが何の#
ためにあるのか疑問に思いました。
#define ASSERT( x ) if ( !( x ) ) { \
int *p = NULL; \
DBGPRINTF("Assert failed: [%s]\r\n Halting.", #x); \
*p=1; \
}
これは「文字列化」前処理演算子です。
マクロパラメータへの引数として渡されたトークンを受け取り、x
それらを文字列リテラルに変換します。
#define ASSERT(x) #x
ASSERT(a b c d)
// is replaced by
"a b c d"
#x
文字列化ディレクティブです
#define Stringify(x) #x
手段 Stringify(abc)
はに置き換えられます"abc"
のように
#define initVarWithItsOwnName(x) const char* p = #x
int main()
{
initVarWithItsOwnName(Var);
std::cout << Var; //will print Var
}
#
プリプロセッサの「文字列化」演算子です。マクロパラメータを文字列リテラルに変換します。ASSERT(foo >= 32)
呼び出した場合は、マクロの評価中にに#x
展開されます。"foo >= 32"
#
セクション6.10.3.2(C99)およびセクション16.3.2で定義されている文字列化演算子です。(C ++ 03)
パラメータ定義を拡張せずに、マクロパラメータを文字列リテラルに変換します。
結果として生じる置換が有効な文字列リテラルでない場合、動作は未定義です。#演算子の評価の順序は指定されていません。
たとえば、構文的には、文字列リテラルでの円記号の出現はエスケープシーケンスに制限されます。
次の例では:
1 #define mkstr(x) # x
2 char *p = mkstr(a \ b);
/* "a \ b" violates the syntax of string literals */
演算子の結果はである#
必要はありません"a \ b"
。
これは、文字列化と呼ばれるプリプロセッサ機能です。それ
[マクロパラメータ]を、文字列定数に変換された実際の引数のリテラルテキストに置き換えます。
あなたが見るものは文字列化と呼ばれます。マクロの引数を文字列リテラルに変換できます。詳細については、 http: //gcc.gnu.org/onlinedocs/cpp/Stringification.htmlを参照してください。