web-dev-qa-db-ja.com

マクロに値を「返す」

マクロを使用していますが、問題なく動作すると思います-

#define CStrNullLastNL(str){char * nl = strrchr(str、 '\ n'); if(nl){* nl = 0;}} 

そのため、文字列の最後の改行をゼロにするように機能します。実際には、fgetsによって残ったときに改行を削除するために使用されます。

だから、マクロから値を「返す」ことができるかどうか疑問に思っているので、それは次のように呼び出すことができます

 func(CStrNullLastNL(cstr)); 

または、関数を作成する必要がありますか

22
bobobobo

マクロが「値を返す」には、マクロ自体が式である必要があります。マクロはステートメントブロックであり、式に評価できません。

あなたは本当にinline関数を書くべきです。それは同じくらい速く、はるかに保守しやすくなります。

31
Mike DeSimone
#define CStrNullLastNL(str) ({ \
    char* nl=strrchr(str,'\n');\
    if(nl){*nl=0;} \
    nl; \
})

うまくいくはずです。

編集:... GCCで。

27
Danvil

マクロは値を返しません。マクロは、#defineの後ろにあるものを#defineの後ろにあるものに置き換えるようにプリプロセッサに指示します。結果は有効なC++でなければなりません。

あなたが求めているのは、以下を有効にする方法です:

func( {char* nl=strrchr(str,'\n'); if(nl){*nl=0;}} );

それを実際の関数呼び出しにする以外に、それを有効なものに変える良い方法は考えられません。この場合、マクロがインライン関数よりも優れている理由がわかりません。それはあなたが本当に求めていることのようです。

6
i_am_jorf

本当にこれを実行したい場合は、C++ 0xスタイルのラムダをサポートするコンパイラを入手してください。

#define CStrNullLastNL(str) [](char *blah) {char* nl=strrchr(blah,'\n'); if(nl){*nl=0;} return blah;}(str)

CStrNullLastNLは基本的には関数なので、おそらく関数として書き直す必要があります。

5
MSN

カンマ演算子を使用できますか?簡略化した例:

#define SomeMacro(A) ( DoWork(A), Permute(A) )

ここで、B = SomeMacro(A)は、Permute(A)の結果を「返し」、「B」に割り当てます。

5
Adisak

マクロのみを使用するという厳密な要件がない場合は、次のようにすることができます(実際の例):

#define Q_XCB_SEND_EVENT_ALIGNED(T) \
    q_xcb_send_event_aligned<T>()

template<typename T> inline
T q_xcb_send_event_aligned()
{
    union {
        T event;
        char padding[32];
    } event;

    memset(&event, 0, sizeof(event));
    return event.event;
}

そして、次のようにコードで使用します。

auto event = Q_XCB_SEND_EVENT_ALIGNED(xcb_unmap_notify_event_t);
4
gatis paeglis

Mikeは100%正しいので+1を与えましたが、これをマクロとして実装する場合は、

char *CStrNullLastNL_nl; // "private" global variable
#define nl ::CStrNullLastNL_nl // "locally" redeclare it
#define CStrNullLastNL( str ) ( \
    ( nl = strrchr( str, '\n') ), /* find newline if any */ \
    nl && ( *nl = 0 ), /* if found, null out */ \
    (char*) nl /* cast to rvalue and "return" */ \
OR  nl? str : NULL /* return input or NULL or whatever you like */
)
#undef nl // done with local usage
4
Potatoswatter

値を返すことがインライン関数の目的です。そしてかなり頻繁に、インライン関数は非常に危険で型を安全に持たないマクロよりもタスクに適しています。

3
Michael Dorgan