我正在使用宏,我觉得它运行正常 -
#define CStrNullLastNL(str) {char* nl=strrchr(str,'\n'); if(nl){*nl=0;}}
因此,它可以将字符串中的最后一个换行清零,实际上它用于在fgets保持开启状态时切断换行符。
所以,我想知道我是否可以从宏中“返回”一个值,所以它可以被称为
func( CStrNullLastNL( cstr ) ) ;
或者我必须写一个函数
答案 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);