2016-10-31 7 views
1

マクロを作成しようとしているので、まだ関数が実装されていないことを指定できます(呼び出されたときにプログラムがクラッシュする)。ここに私が思い付いたものです:機能は実装されていないマクロですか?

#define NIMPL crash(__PRETTY_FUNCTION__ " not implemented yet") 

そして、あなたがそうのようにそれを使用したい:しかし

void myFunction() { 
    NIMPL; 
} 

、この使用法は、このエラーが発生します。

../feta/include/feta.h:19:41: error: expected ‘)’ before string constant 
#define NIMPL crash(__PRETTY_FUNCTION__ " not implemented yet") 
             ^

crash()は関数であること1つの文字列をパラメータとして受け取り、メッセージを出力し、exit(1)を呼び出します。

__PRETTY_FUNCTION__単独でも、連結がうまく機能しないことが確認できます。また、__PRETTY_FUNCTION__を使用せずに2つの文字列を連結すると、正常に動作します。"<stuff>""<other stuff>"。しかし、同時に両方を行うことは機能しません。

私はstringizing operatorを使ってみましたが、(GCCに存在する場合でも)うまくいきませんでした。

+1

Cの場合、 '__Punc'_FUNCTION__とは異なり、' __func__'を使うこともできます。 '__PRETTY_FUNCTION__'はC++の' __func__'とは異なります。 (これはあなたの問題を解決しません) –

+0

2つの文字列の間には##がありません。 – pm100

+0

@ pm100: '__PRETTY_FUNCTION__'はマクロではなく' char [] 'オブジェクトの名前として扱われるので、' ## 'は役に立たない。 –

答えて

3

標準CおよびC++、それが現在の関数の名前を含む静的char配列の名前であるかのように作用する「魔法識別子」__func__を、提供します。 (実際にはC++で実装定義されています)。__PRETTY_FUNCTION__は、Cの場合は__func__と同じで、C++のいくつかの追加情報を提供します。

文字列リテラルの連結は文字列リテラルにのみ適用されますが、それはあなたが求めている問題を解決しません。

あなたのcrash()関数は引数として単一の文字列を取るとします。

crash()を修正するか、2つの引数を取るか、2つの引数をとる新しいラッパー関数を書くようにしてください。その後、使用することができます。

#define NIMPL crash(__PRETTY_FUNCTION__, " not implemented yet") 

二つの文字列を連結(。あなたが同じ名前でそれをオーバーロードすることができ、C++を使用しているので)運動として残っています。

既存のcrash()関数に2番目の文字列引数を追加して、既定値の""を指定して、既存の呼び出しを壊さないようにすることもできます。

2

Cでは(質問に元々付いていたように)__PRETTY_FUNCTION__は別の名前の__func__ですが、文字列リテラルではありません。 C++では、関数シグネチャで装飾されていますが、文字列リテラルではありません。 documentationから

(特に最後の文に注意してください):あなたがC++を使用しているので

The identifier __func__ is implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration

static const char __func__[] = "function-name"; 

appeared, where function-name is the name of the lexically-enclosing function. This name is the unadorned name of the function. As an extension, at file (or, in C++, namespace scope), __func__ evaluates to the empty string.
...
In C, __PRETTY_FUNCTION__ is yet another name for __func__ , except that at file (or, in C++, namespace scope), it evaluates to the string "top level" . In addition, in C++, __PRETTY_FUNCTION__ contains the signature of the function as well as its bare name.
...
These identifiers are variables, not preprocessor macros, and may not be used to initialize char arrays or be concatenated with string literals.

、あなたはいくつかのより多くの柔軟性を提供するために、可変引数テンプレート関数ではなくマクロとしてcrashを定義することを検討します。

void crash_t (std::ostringstream &oss) 
{ 
    oss << std::endl; 
    write(2, &oss.str()[0], oss.str().size()); 
    exit(1); 
} 

template <typename A, typename... REST> 
void crash_t (std::ostringstream &oss, A arg, REST... rest) 
{ 
    oss << arg; 
    crash_t(oss, rest...); 
} 

template <typename... ARGS> 
void crash (ARGS... args) 
{ 
    std::ostringstream oss; 
    crash_t(oss, args...); 
} 
+0

私は' __FUNCTION__'と '__func__'が同じで、両方とも" myFunction "を出力しますが、' __PRETTY_FUNCTION__' "void myFunction()"を出力します。 –

+0

@ChrisSmith: '__PRETTY_FUNCTION__'がvoid myFunction()を返す場合、CではなくC++をコンパイルしています。質問のタグが使用している言語と一致していることを確認してください。 –

+0

次に、C++としてコンパイルしています。 – jxh

関連する問題