让宏'返回'一个值

时间:2010-04-20 22:34:54

标签: c++ macros return-value

我正在使用宏,我觉得它运行正常 -

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

因此,它可以将字符串中的最后一个换行清零,实际上它用于在fgets保持开启状态时切断换行符。

所以,我想知道我是否可以从宏中“返回”一个值,所以它可以被称为

func( CStrNullLastNL( cstr ) ) ;

或者我必须写一个函数

9 个答案:

答案 0 :(得分:30)

对于“返回值”的宏,宏本身必须是一个表达式。您的宏是一个语句块,无法计算表达式。

你真的应该写一个inline函数。它将同样快速且更易于维护。

答案 1 :(得分:24)

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

应该有用。

编辑:...在海湾合作委员会。

答案 2 :(得分:5)

宏不返回值。宏告诉预处理器将#define之后的内容替换为#define之后的内容。结果必须是有效的C ++。

您要求的是如何使以下内容有效:

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

除了让它成为真正的函数调用之外,我无法想到将其转换为有效内容的好方法。在这种情况下,我不确定为什么宏会比内联函数更好。这似乎是你真正要求的。

答案 3 :(得分:4)

如果你真的想这样做,那就得到一个支持C ++ 0x style lambdas的编译器:

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

虽然CStrNullLastNL基本上是一个函数,但您应该将其重写为函数。

答案 4 :(得分:4)

您可以使用逗号运算符吗?简化示例:

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

这里B = SomeMacro(A)“返回”Permute(A)的结果并将其分配给“B”。

答案 5 :(得分:3)

我给迈克+1,因为他100%正确,但如果你想把它作为一个宏来实现,

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

答案 6 :(得分:3)

如果你没有严格要求只使用宏,你可以做这样的事情(现实生活中的例子):

#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);

答案 7 :(得分:2)

返回值是内联函数的用途。而且很多时候,内联函数比宏更适合于任务,宏非常危险并且没有安全类型。

答案 8 :(得分:0)

从宏返回值:

bool my_function(int a) {
    if (a > 100)return true;
    return false;
}
bool val = my_function(200);

#define my_macro(ret_val,a){\
    if(a > 100 ) ret_val = true;\
    ret_val = false;\
}
bool val; my_macro(val, 200);