Have macro 'return' a value - c++

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 newline in a string, really its used to chop off the linebreak when it gets left on by fgets.
So, I'm wondering if I can "return" a value from the macro, so it can be called like
func( CStrNullLastNL( cstr ) ) ;
Or will I have to write a function

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.

#define CStrNullLastNL(str) ({ \
char* nl=strrchr(str,'\n');\
if(nl){*nl=0;} \
nl; \
})
should work.
Edit: ... in GCC.

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.

If you really want to do this, get a compiler that supports C++0x style lambdas:
#define CStrNullLastNL(str) [](char *blah) {char* nl=strrchr(blah,'\n'); if(nl){*nl=0;} return blah;}(str)
Although since CStrNullLastNL is basically a function you should probably rewrite it as a function.

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".

I gave +1 to Mike because he's 100% right, but if you want to implement this as a macro,
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

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

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.

to return value from macro:
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);

Related

How can I get full, expanded, stringified macros from boost::wave?

I have a file containing the following:
#define str(s) s
#define xstr(s) #s
#define foo 4
#define first str(foo)
#define second xstr(foo)
When I pass this into boost::wave, the macromap contains the following:
first=str(foo)
foo=4
second=xstr(foo)
str(s)=#s
xstr(s)=str(s)
How can I get the macros to be fully expanded such that:
first="foo"
second=4
I thought that boost::wave supported macro re-scanning and lookup. Is there something I'm missing, or do I need to do something with the processing hooks to make the expansion happen? I mean, I can write code to descend the tree, but it would be certainly nice if I didn't have to do that work if I was missing something important.
The clue from n.m. was important. Macros may be defined and undefined whenever, so it's only the instance of use which is relevant.
This was far easier than I had expected. If I have something that looks like this in a header file:
#define str(s) #s
#define xstr(s) str(s)
...
#define MAJORVER 1
#define MINORVER 0
#define MAJORBUILD 0
#define MINORBUILD 1
#define FULLBUILDSTRING xstr(MAJORVER) "." \
xstr(MINORVER) "." \
xstr(MAJORBUILD) "." \
xstr(MINORBUILD)
The FULLBUILDSTRING macro will evaluate to just the string as declared. However, if I have some code that makes use of the macro directly, such as in
static char const full_build_string[] = FULLBUILDSTRING;
It will evaluate to the following when Wave processes it:
static char const full_build_string = "1" "." "0" "." "0" "." "1";
If you need to see how the macros are defined after processing is complete, you can always do something like so (this is taken from the Wave driver code):
auto end = ctx.macro_names_end();
for (auto it = ctx.macro_names_begin(); it != end; ++it) {
typedef std::vector<context_type::token_type> parameters_type;
bool has_pars = false;
bool predef = false;
context_type::position_type pos;
parameters_type pars;
context_type::token_sequence_type def;
if (ctx.get_macro_definition(*it, has_pars, predef, pos, pars, def)) {
// if has_pars is true, you can iterate through pars to see
// parameters for function macros
// iterate through def to see the macro definition
}
}
Of course, the macros are stored in non-expanded form.
(n.m., if you write an answer, I will accept it)

Replace C macro for a function call with a C++ template?

Is it possible to replace this preprocessor macro:
#define AL_CALL(a) do { a; \
ALenum e = alGetError(); \
if(e != AL_NO_ERROR) \
UtilitySoundNode::printALError(e,__FILE__, __LINE__); \
} while(0)
with a C++ template? If it is possible, will make any sense to do it (pros/cons - overhead/debugging)?
Note:
Basically I am wondering if there is an elegant way to handle this kind of error handling in C++.
EDIT:
Of course I made a mistake a is a function call. As one may guess it is a function call with parameters of a OpenAL function.
AL_CALL(someAlFunction(param1, param2))
NOTE:
Somebody decided to edit the macro and make it nicer but I'd prefer to keep the original one too. So here it is:
#define AL_CALL(a) {a; ALenum e = alGetError();if(e != AL_NO_ERROR)PUtilitySoundNode::printALError(e,__FILE__, __LINE__);}
One problem here seems to be that the "a" can be some arbitrary function (with parameters) which sets the error code returned by alGetError().
That can be rewritten to C++ by using a functor object. To pass the arguments (and object instance if necessary) std::bind or boost::bind can be used (note that to bind reference args the std::ref/boost::ref is necessary).
However, if you'd want to still have the __FILE__ and __LINE__ passed the the printError() that C++ template still would need to be called by a macro which will pass those to the template. __FILE__ and __LINE__ are only expanded by the preprocessor, so there is no way around using a macro for them.
But the macro could be much simpler then and most of the work can be done in the C++ template (which has many advantages e.g. for debugging, because in most debuggers you cannot step into a macro).
EDIT: adding the code as an example:
template<typename T>
void ALcallAndCheck(T c, const char *file, size_t line)
{
c();
ALenum e = alGetError();
if(e != AL_NO_ERROR)
UtilitySoundNode::printALError(e, file, line); \
}
#define AL_CALL(a) ALcallAndCheck(a, __FILE__, __LINE__)
Then, instead of
AL_CALL(SomeFunction(2, refAttr));
the call will become:
AL_CALL(std::bind(SomeFunction, 2, std::ref(refAttr)));
EDIT 2:
The previous indeed does not work with expressions, which the original macro allows. To work also for expressions, the macro can be altered to:
#define AL_CALL(a) ALcallAndCheck([&]{ (a); }, __FILE__, __LINE__)
That will create a lambda which will evaluate anything that comes into the macro. Then even the std::bind is not necessary and it can be called directly as:
AL_CALL(SomeFunction(2, refAttr));
AL_CALL(SomeOtherFunction1()+SomeOtherFunction2(8));
No, the use of __FILE__ and __LINE__ pretty well require the preprocessor.
Note that using a template instead of a macro does not produce an exact analog. The macro defined in your question allows a to represent a statement as well as an expression. A template does not have that kind of flexibility. The template defined below assumes a is a non-void expression.
There is no standard way to implicitly inject a function caller's file name and line number without the caller passing in that information to the called function. A preprocessor macro allows a means to make the syntax appear to be implicit injection, when in fact the information is being passed.
template <typename T>
void AL_CALL (T a, const char *file, int line) {
ALenum e = alGetError();
if(e != AL_NO_ERROR)
UtilitySoundNode::printALError(e, file, line);
}
#define AL_CALL(X) AL_CALL((X), __FILE__, __LINE__)
You may be able to use system specific facilities (e.g., CaptureStackBackTrace + SymFromAddr or backtrace + backtrace_symbols) to get approximately the same information implicitly, but it may require debugging symbols to be present, and inline functions may not produce the expected output.
template<class A>
void al_call(A&&a){
ALenum e = a();
if(e != AL_NO_ERROR)
UtilitySoundNode::printALError(e,__FILE__, __LINE__);
}
Use:
al_call( [&]{ return bob(); });
Instead of:
AL_CALL( bob() )
The line/file info is not useful above.
So
template<class A>
void al_call(A&&a, char const*file, unsigned line){
ALenum e = a();
if(e != AL_NO_ERROR)
UtilitySoundNode::printALError(e,file, line);
}
#define AL_CALL(...) al_call([&]()mutable{return __VA_ARGS__;}, __FILE__, __LINE__)
and it is almost a drop in replacement.

#define not executing all arguments

I am having trouble with a #define I have made. For some reason it is not checking all the arguments in the statement.
THROW_AND_LOG(Foo::Initialize() && Bar::Initialize() && FooBar::Initialize(), "Something() could not Initialize singletons.");
For some reason it is only initializes Foo and then exits the statement. It does not throw or log.
However
THROW_AND_LOG((Foo::Initialize() && Bar::Initialize() && FooBar::Initialize()), "Something() could not Initialize singletons.");
works fine for some reason. (Wrapped all the checks in brackets).
I am going to move everything on to its own seperate line to fix this as its not the best code in the first place. I am curious however of why it would not execute all statements.
Here is the define:
#define THROW_AND_LOG(x, message) if(!x) { throw std::runtime_error(message); \
LOG::v1::MessageSender messageSender("log"); \
LOGGING_ERROR(messageSender,message);}
After the macro expansion,
if(!x)
transforms to
if(!Foo::Initialize() && Bar::Initialize() && FooBar::Initialize())
Foo::Initialize() presumably returns true, so !Foo::Initialize() is false and other terms are not executed (not mentioning that their meaning has changed to the opposite).
It's not expanding the way you think it is. You want (!(x)) in your macro.
With the macro definition
#define THROW_AND_LOG(x, message) if(!x) { throw std::runtime_error(message); \
LOG::v1::MessageSender messageSender("log"); \
LOGGING_ERROR(messageSender,message);}
the invocation
THROW_AND_LOG(Foo::Initialize() && Bar::Initialize() && FooBar::Initialize(), "Something() could not Initialize singletons.");
yields the condition
if(!Foo::Initialize() && Bar::Initialize() && FooBar::Initialize())
which is equivalent to
if((!Foo::Initialize()) && Bar::Initialize() && FooBar::Initialize())
A good fix is to replace the macro with a function:
void throw_and_log_if(
const bool condition,
const Location& location,
const string& message )
{
LOG::v1::MessageSender messageSender( "log" );
LOGGING_ERROR( messageSender, message ); }
throw std::runtime_error( message );
}
where Location is some class representing file and line number, which you can pick up via the __FILE__ and __LINE__ macros.
I took the liberty of fixing the bug causing logging to not be performed.
A short term easier fix is to use parenthesis around the x in the macro's condition.
If you choose that, then do remember to fix the bug in the macro.

Not able to understand if in #define

Can anyone help me to understand the meaning of this line?
I know it's kind of macro structure, but what does , suggest in the code??
#define ReturnErr(fCall) if (iErr = (fCall), (iErr != NO_ERRORS)) {return iErr;}
A qualified guess is that the macro is meant to be used like this:
err_t func (void)
{
err_t iErr;
ReturnErr(some_function());
...
return NO_ERRORS;
}
In that case the macro expands to:
err_t func (void)
{
err_t iErr;
if(iErr = some_function(), iErr != NO_ERRORS) { return iErr; }
...
return NO_ERRORS;
}
which in turn is just a needlessly obfuscated way of writing
err_t func (void)
{
err_t iErr;
iErr = some_function();
if(iErr != NO_ERRORS)
{
return iErr;
}
...
return NO_ERRORS;
}
In other words, the macro is likely an attempt from repeating the same error handling code over and over.
Macros are a text substitution. It means that if someone writes, for example,
ReturnErr(x)
then their code will be processed as:
if ( iErr = (x), (iErr != NO_ERRORS) )
{
return iErr;
}
This is bad style, but they probably want to have their function return when a failure occurs and save some typing over copying out that code at each point they need to check an error code.
The macro takes a single argument named fCAll. The macro expands to the following code:
if (iErr = (fCall), (iErr != NO_ERRORS)) {
return iErr;
}
I guess you are confused by the usage of the , operator in the if statement.
In the C and C++ programming languages, the comma operator (represented by the
token ,) is a binary operator that evaluates its first operand and discards the
result, and then evaluates the second operand and returns this value (and type).
This is quote from the wikipedia article btw.
Thus the statement in the body will be executed if and only if iErr != NO_ERRORS i.e. there are errors.
The macro wants to use the value iErr twice, once in the if and once in the return, but
it wants to execut fCall only once. It uses the comma which evaluates both its operands but is equal only to the right-most.
Thus if we expand by hand and do a little refactoring, we get:
iErr = (... macro argument here ...);
if((iErr != NO_ERRORS)) {
return iErr;
}
Lundin and others have explained what the author of the macro intended. However, the way it is written it can have unintended consequences too, because it doesn't follow the canonical way of writing multi-statement macros, which is: wrap it in a do..while(0) loop.
Why? Consider:
if( someCondition) ReturnErr(fCall); else doSomethingElse();
This fails syntactically because the programmer's semicolon behind the expanded macro's curly brace is an empty statement, making the else dangling.
The programmer may choose to remove the superfluous semicolon in order to mollify the compiler, writing
if( someCondition) ReturnErr(fCall) else doSomethingElse();
This is probably not what s/he intended, because the else part is now silently attached to the macro's if. That's pretty bad because it's totally invisible.
The canonical way is:
#define ReturnErr(fCall) do { if (iErr = (fCall), (iErr != NO_ERRORS)) \
return iErr; \
} while(0)
This allows, even requires the syntactically natural semicolon at the end and counts as a single statement whenever one is needed.
#Jens: :-)

C++ macro expansion to function body

I would like to be able to write a macro CONDITIONALFUNCTION so that
CONDITIONALFUNCTION( FunctionName )
{
ConditionalExpression()
}
expands to
bool FunctionName( const Arguments& args )
{
return ConditionalExpression();
}
Is this even possible?
The closest I can find on SO is this thread:
Possible to define a function-like macro with a variable body?
except unlike in that thread, I have the additional requirement that the "body" within the braces is not a complete valid C++ statement, but rather an expression to be wrapped (effectively) in an 'if' statement.
Please assume I already know this may be impossible, and is almost surely stupid and evil :)
I'm going to assume you've got a good reason for using macros in the first place...
It's not possible with the syntax you've given with the question.
The closest workable macro syntax is:
#define CONDITIONALEXPRESSION(f, c) \
bool f( const Arguments& args ) \
{ return c; }
CONDITIONALEXPRESSION(FunctionName, ConditionalExpression())
This will expand to the same as the expanded function in the question
Is there any reason why the function body must be defined in the macro? In Microsoft C++, macros like ASSERT() define the actual function separately and then just reference it from the macro.
So the function is always defined but the macro is either equal to calling the function or nothing at all.
Aside from that, for C++ I'd probably use an inline function.
je4d already provided one alternative. I over some other variation:
#define CONDITIONALEXPRESSION(f) \
bool f( const Arguments& args )
#define CONDITIONALRETURN(c) \
return (c)
CONDITIONALEXPRESSION(FunctionName)
{
CONDITIONALRETURN(ConditionalExpression())
}