Not able to understand if in #define - c++

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

Related

Macro for while loop with deferred function call

I would like to construct a macro where a predefined function (here simulated by "call fcn here") is called every time when the loop ends an iteration. This is what I have so far, which actually works.
Is there shorter way, eventually with more macro magic to write such behavior?
#define MYWHILE(condition) \
while( \
[]()->bool { \
static bool called = false; \
if(called) std::cout<<"call fcn here"<<std::endl; \
called=true; return true;}() \
&& condition)
This macro should than be used on several places in the code to ensure than nobody forgets to call the function when they write busy waiting loops.
A typical example would be:
while(true){
bool b = foo();
if(b){
break;
}
ros::spinOnce();
}
Where oft the call ros::spinOnce() is forgotten, so I simply replace the sample code with:
MYWHILE(true){
bool b = foo();
if(b){
break;
}
}
Pure C - Code would also be fine.
Rather than a complicated looking while loop, you can package up what you need into a for loop:
for (; condition; fcn())
The function will be called at the end of every iteration, before reevaluating the condition.
I would like to construct a macro where a predefined function (here
simulated by "call fcn here") is called every time when the loop ends
an iteration, but NOT at the first time.
Since your provided code and your question conflict, it is not clear what behavior you want. To implement the above, I would recommend not using macros at all and simply writing your code as:
do {
if(!condition)
break;
// More code here
} while(fcn());
What's wrong with just:
while(!foo()) {
ros::spinOnce();
}
That is logically equivalent to:
while(true){
bool b = foo();
if(b){
break;
}
ros::spinOnce();
}
Yet far simpler than:
MYWHILE(true){
bool b = foo();
if(b){
break;
}
}

C++ sugar syntax for if (!result) return false;

When refactoring some code, I often encounter this :
bool highLevelFunc foo()
{
// ...
bool result = LesserLevelFunc();
if (!result) return false;
// ... Keep having fun if we didn't return
}
Is there any way to make this a little more sexy and less verbose ? Without any overhead or pitfall of course.
I can think of a macro
#define FORWARD_IF_FALSE(r) if (!r) return r;
bool highLevelFunc foo()
{
// ...
FORWARD_IF_FALSE(LesserLevelFunc());
// ...
}
Anything better, i.e without preprocessor macro?
To me, "readable" code is sexy. I find the original code more readable than your proposal, since the original uses standard C++ syntax and the latter uses a macro which I'd have to go and look up.
If you want to be more explicit, you could say if (result == false) (or better yet, if (false == result) to prevent a possible assignment-as-comparison bug) but understanding the ! operator is a fairly reasonable expectation in my opinion.
That said, there is no reason to assign the return value to a temporary variable; you could just as easily say:
if (!LesserLevelFunc()) return false;
This is quite readable to me.
EDIT: You could also consider using exceptions instead of return values to communicate failure. If LesserLevelFunc() threw an exception, you would not need to write any special code in highLevelFunc() to check for success. The exception would propagate up through the caller to the nearest matching catch block.
Because you might be continuing if LesserLevelFunc returns true, I suggest keeping it pretty close to how it is now:
if (!LesserLevelFunc())
return false;
First of all introducing the macro you are making the code unsafe. Moreover your macro is invalid.
The expression after the negation operator shall be enclosed in parentheses.
#define FORWARD_IF_FALSE(r) if (!( r ) ) return r;
Secondly the macro calls r twice. Sometimes two calls of a function is not equivalent to one call of the same function. For example the function can have some side effects or internal flags that are switched on/off in each call of the function.
So I would keep the code as is without introducing the macro because the macro does not equivalent to the symantic of the original code.

C - do{..} while(0); can be removed from code excluding usage nested if else?

do{...} while(0);
the usage of do{}while(0); in my coding is used because, i do not want to use long if else nested conditional statements. I eventually give an break at the time of failure and move out of the loop, with a assurance that my function would have been traversed at least 1 time.
Now, the problem comes with the code warning tools, I am getting a warning at the usage of do{...}while(0);
the usage of nested if(){} else{} is less readable, high complex. and lets the code to be having dead code.
if i exclude nested if(){} else{} and do{} while(0); , do we left part with some other way to make code readable with understandable logic;
if(status_of_funcA_ok != funcA())
{ //failure}
else if (status_of_funcB_ok != funcB())
{//failure}
else if (status_of_funcC_ok != funcC())
else
{//Great}
do{
if(status_of_funcA_ok != funcA())
break;
if (status_of_funcB_ok != funcB())
break;
if (status_of_funcC_ok != funcC())
break;
}while(0);
Move the complete logic of the do while{0} loop to a function, and replace the break with return. And call the function, instead of the loop.
You will not have to worry about the beauty.
The compiler also doesn't have to complain about the do while{0}.
All the more, by adding a bit of modularity, the program might be a little more readable.
In any case, before doing this, it would be nice to check whether your compiler is in an extremely pedantic mode, and you might want to turn that off. That might take the warning away.
ss.
PS: You don't seem to need a return value for the function, but you could have that to get a clue of which function was successful.
I am using this pattern too, for those who wonder, here's an abstract example:
do // while(0) for break
{
state1 = 0;
if (cond1())
{
if (cond2())
break;
state1 = opA();
}
if (cond3() || state1 && state1->cond4())
break;
...
Triumph(state1, ...);
// often here: return
}
Failure(state1, ...);
I consider this valid in the following circumstances:
you have a long-ish sequence (say, >~half a dozen of conditions)
the conditions are complex, and you use / build up significant state, so you can't
isolate the elements into functions
you are in an exception-unfriendly environment, or your break-ing code path is
not actually an exception
What you can do about it:
Silence the warning. It is just a warning, after all; and I don't see a "typical mistake" (like typing 0 instead of your condition) that would be caught by this warning.
[edit] Now, that was silly. the typical mistake that you catch with the warning is e.g. while (a1!=a1) instead of while (a1!=a2).[/edit]
Break into functions, move state to a class
this would transform above code to:
struct Garbler
{
State1 state1;
bool Step1()
{
state1 = 0;
if (cond1())
{
if (cond2())
return false;
state1 = opA();
}
return true;
}
bool Step2()
{
return cond3() || state1 && state1->cond4();
}
..
void Run()
{
if (Step1() && Step2() && ... && Step23())
Triumph(state1, ...);
else
Failure(state1, ...);
}
}
This is arguably less readable, worse is that you pull apart the sequence, which might lead to a very questionable class (where members may be called only in a certain order).
Scopeguards
This may allow to transform the breaks into early returns, which are more acceptable:
state1 = 0;
ScopeGuard gFailure = MakeGuard(&Failure, ByRef(state1), ...);
if (cond1())
{
if (cond2())
return;
state1 = opA();
}
if (cond3() || state1 && state1->cond4())
return;
// everything went ok, we can dismiss the scopeguard
gFailure.Dismiss();
Triumph(state1, ...);
They can be more elegantly written in C++0x, preserve the flow, but the solution isn't that flexible either, e.g. when Failure() cannot be isolated easily into a single function.
Nested nested if-else statements can become quite unreadable, but I think using do {..} while(0); as a replacement would be much worse. It is very unconventional and anybody else reading it would not really associate it with if-else statements.
There are a few things you can do to make nested if-else statements more readable. A few suggestions are:
optimize your logic - sometimes you can do away with a lot of if clauses when you 'refactor' your logic ex. grouping identical items.
use switch() - switch is generally more readable compared to if-else statements. You can associate an enum to each case and you can switch this.
encapsulate complicated logic with functions
You can use goto instead of do {} while(0) and break. This is not readable and not good practice either though. I think for each specific case there is a better way to avoid deep if/else structures. For example, sometimes using function calls can help:
for example instead of:
if(status_of_funcA_ok != funcA())
{ //failure}
else if (status_of_funcB_ok != funcB())
{//failure}
else if (status_of_funcC_ok != funcC())
else
{//Great}
you can write:
if (check_funcs() == 0) {
great();
}
int check_funcs() {
if (status_of_funcA_ok != funcA())
return -1;
if (if(status_of_funcB_ok != funcB()))
return -2;
if (if(status_of_funcC_ok != funcC()))
return -3;
return 0; /* great */
}
Sometimes, you can use exit().
Also, in c++ you can use throw() and try/catch:
try {
/* */
throw (this error);
/* */
throw (that error);
} catch (this error) {
} catch (that error) {
}
If there are more conditions to check avoid using if{} else{},
best practice is to Replace if else conditions with switch case

do while(false) pattern [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?
Why is the do while(false) necessary in the macros below?
#define LOG(message, ...) \
do { \
Lock<MutualExclusion> lock (logMutex); \
.... a lot of code ...
} while (false)
I dont think it serves any functional purpose. Am I overlooking something?
It turns a block into a single statement. If you just use a block (i.e. code enclosed in {}) strange things can happen, for example
#define STUFF() \
{ do_something(); do_something_else(); }
if (cond)
STUFF();
else
//...
the extra semi-colon breaks the syntax. The do {} while(false) instead is a single statement.
You can find more about this and other macro tricks here.
So you are forced to add semicolon at the end of the macro, when you use it. This is a common idiom and only way to enforce it.
If somebody has code that does this:
if (something)
LOG("My log message");
That would expand to:
if (something)
Lock<MutualExclusion> lock (logMutex);
// A bunch of other code
Which is incorrect (only the first line would be under the if statement).
The macro makes sure that the macro call is inside of a block of code.
People use it because otherwise, you can screw up your ifs with compound statements. Imagine
#define hai int x; \
x = 0;
if (condition)
hai;
else
func();
Imagine what the preprocessed source looks like.
if (condition)
int x;
x = 0;
else
func();
Oh wait- now our else doesn't work.
Macros like that however are typically unnecessary in C++.
The reason for this weird practice in #define's is to encapsulate the different assignments within a loop that is executed exactly once, so one may use the macro like a function. For example, with the code you posted, one can write:
if(...)
LOG(x, y);
else
// Something else
and it is expanded as
if(...)
do {...} while(false);
else
// Something else
This would not work without the do...while(false) surrounding the different assignments, because that would be expanded as
if(...)
Lock<MutualExclusion> lock (logMutex);
// Other code... Outside the if statement!
Also forcing a semicolon after the macro makes it look like a function and you wont get errors because you added an semicolon like after a normal function.
It provides local scope to that which is inside the macro.
It looks to me like it is only used for scoping rules, so that Lock<MutualExclusion> falls out of scope at the end of the block.
If that's the reason for it, then it's completely unnecesarry:
// some other code...
string s = "oh hai";
{
Lock<MutualExclusion> lock(logMutex);
// MAGIC HAPPENS
}
s = "oh bai";

Have macro 'return' a value

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