I\'m using a macro and I think it works fine -
#define CStrNullLastNL(str) {char* nl=strrchr(str,\'\\n\'); if(nl){*nl=0;}}
So it works to zero out the last
Macro's don't return values. Macros tell the preprocessor to replace whatever is after the #define
with whatever is after the thing after the #define
. The result has to be valid C++.
What you're asking for is how to make the following valid:
func( {char* nl=strrchr(str,'\n'); if(nl){*nl=0;}} );
I can't think of a good way to turn that into something valid, other than just making it a real function call. In this case, I'm not sure why a macro would be better than an inline function. That's seems to be what you're really asking for.
Returning a value is what inline functions are for. And quite often, said inline functions are better suited to tasks than macros, which are very dangerous and have no type safetly.
#define CStrNullLastNL(str) ({ \
char* nl=strrchr(str,'\n');\
if(nl){*nl=0;} \
nl; \
})
should work.
Edit: ... in GCC.
If you don't have a strict requirement to use only macro, you can do something like this (real life example):
#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;
}
And then use it in your code like this:
auto event = Q_XCB_SEND_EVENT_ALIGNED(xcb_unmap_notify_event_t);
For a macro to "return a value", the macro itself has to be an expression. Your macro is a statement block, which cannot evaluate to an expression.
You really ought to write an inline
function. It will be just as fast and far more maintainable.
Can you use the comma operator? Simplified example:
#define SomeMacro(A) ( DoWork(A), Permute(A) )
Here B=SomeMacro(A) "returns" the result of Permute(A) and assigns it to "B".