This code I found while doing code review. Is there any hidden problem in this code or is it just fine?
myBool = myBoolA || ( oldState == AS_PLAYING ); //code #1
Edit: One typing mistake (myBoolA in place of myBool) by me created some nasty confusion; I am really sorry for that.
Actually the code to be reviewed is :
myBool = myBool || ( oldState == AS_PLAYING ); //code #1, not myBoolA
and my suggested code is:
if( oldState == AS_PLAYING ) myBool = true; //code #2
Advantages with code#2 IMO :
better readability
if myBool is unintialized to begin with, there won't be Undefined behaviour.
myBool = myBoolA || ( oldState == AS_PLAYING ); is absolutely fine.
|| is a sequencing point in C++, so even if the expression on the right hand side depends on the left hand side (perhaps oldState is a reference to myBool or myBoolA), the behaviour will be defined.
Your recommendation in changing this to
if( oldState == AS_PLAYING ) myBool = true;
is actually functionally different (the assignment to myBool is different for example), so don't change it to that.
Finally, note that the short-circuiting nature of || is obviated if || is overloaded. So always check that when refactoring code.
myBool = myBoolA || ( oldState == AS_PLAYING ); //code #1
seems to be correct version.
Your version is not equivalent to this. How? See
if myBoolA is true and ( oldState == AS_PLAYING ) is false. myBool will still be true, but in your version, it will not be set.
After EDIT
if( oldState != AS_PLAYING ) myBool = false; //code #2 more readable IMO
This will be fine only if, myBool is initialized with true.
As per your comments later,
You can refactor as follows:
if(!myBool)
myBool = (oldState == AS_PLAYING);
this will save one extra assignment operation. when myBool is true before if
Related
bool x = someFuncThatReturnsTrueorFalse();
if (!x && (str1.length() != str2.length()) {
// do nothing
} else {
// do something
}
How would I rearrange the code above to eliminate the else statement?
I need to do nothing if bool = false and str1 and str2 have different lengths. Otherwise, I need to do something (e.g. function call).
For the life of me, I can't think of any way to change this. Let me know if you need further details.
The simplest way is putting !() around the condition.
bool x = someFuncThatReturnsTrueorFalse();
if (!(!x && (str1.length() != str2.length())) {
// do something
}
Another way is using De Morgan's laws: !(A && B) is equivalent to !A || !B.
bool x = someFuncThatReturnsTrueorFalse();
if (x || (str1.length() == str2.length()) {
// do something
}
There is nothing wrong leaving as is. The code will still compile
I'm thought about how to do many actions in single ternary statement, but finished with almost the same as the common IF. So which is better, or there is no differences?
video[0].muted ? (
video[0].muted = false,
vb.attr("data-value", "loud")
) : (
video[0].muted = true,
vb.attr("data-value", "off")
);
//
if(video[0].muted) {
video[0].muted = false;
vb.attr("data-value", "loud");
} else {
video[0].muted = true;
vb.attr("data-value", "off");
}
A nice clean way of writing this that uses plain negation and a ternary would be:
var v = video[0];
// Negate the muted attribute
v.muted = !v.muted;
// And use a ternary to decide the value of this one
vb.attr("data-value", v.muted ? "off" : "loud");
Notice how the ternary is just being used here to decide which String to use.
Don't use ternarys to carry out side effects though. That's not what they're for, and abusing them never helps code readability. If you need side effects (mutating some variable), just use a plain if...else. They're much more readable.
I have a condition like the following where I just want to have the second bool be the trigger for a single time, since this condition is invoked relatively often I don't like the idea of doing the assignment of it being false every time the condition is true so, I tried to take advantage of the order of logical AND and OR and the post increment operator. But it appears to work don't do what I expected it to do. So is there a way to make a post state switch for this line?
where firstTitleNotSet is:
bool firstTitleNotSet;
if (titleChangedSinceLastGet() || (p_firstTitleNotSet && p_firstTitleNotSet++))
The idea is that the first part is the primary trigger and the second is the trigger that only has to trigger the first time.
While I easily could do
if (titleChangedSinceLastGet() || p_firstTitleNotSet)
{
firstTitleNotSet = false;
//...
}
I don't like this as it is reassigning false when ever the conditional block is invoked.
So is there some way of "post change" the value of a bool from true to false? I know that this would work the other way around but this would negate the advantage of the method most time being the true trigger and therefor skipping the following check.
Note: The reasons for me making such considerations isntead of just taking the second case is, that this block will be called frequently so I'm looking to optimize its consumed runtime.
Well, you could do something like:
if (titleChangedSinceLastGet() ||
(p_firstTitleNotSet ? ((p_firstTitleNotSet=false), true):false))
An alternative syntax would be:
if (titleChangedSinceLastGet() ||
(p_firstTitleNotSet && ((p_firstTitleNotSet=false), true)))
Either one looks somewhat ugly. Note, however, that this is NOT the same as your other alternative:
if (titleChangedSinceLastGet() || p_firstTitleNotSet)
{
p_firstTitleNotSet = false;
//...
}
With your proposed alternative, pontificate the fact that p_firstTitleNotSet gets reset to false no matter what, even if the conditional was entered because titleChangedSinceLastGet().
A more readable way than the assignment inside a ternary operator inside an or inside an if would be just moving the operations to their own statements:
bool needsUpdate = titleChangedSinceLastGet();
if(!needsUpdate && firstTitleSet)
{
needsUpdate = true;
firstTitleSet = false;
}
if(needsUpdate)
{
//...
}
This is likely to produce very similar assembly than the less readable alternative proposed since ternary operators are mostly just syntactic sugar around if statements.
To demonstrate this I gave GCC Explorer the following code:
extern bool first;
bool changed();
int f1()
{
if (changed() ||
(first ? ((first=false), true):false))
return 1;
return 0;
}
int f2()
{
bool b = changed();
if(!b && first)
{
b = true;
first = false;
}
return b;
}
and the generated assembly had only small differences in the generated assembly after optimizations. Certainly have a look for yourself.
I maintain, however, that this is highly unlikely to make a noticeable difference in performance and that this is more for interest's sake.
In my opinion:
if(titleChangedSinceLastUpdate() || firstTitleSet)
{
firstTitleSet = false;
//...
}
is an (at least) equally good option.
You can compare the assembly of the above functions with this one to compare further.
bool f3()
{
if(changed() || first)
{
first = false;
return true;
}
return false;
}
In this kind of situation, I usually write:
bool firstTitleNotSet = true;
if (titleChangedSinceLastGet() || firstTitleNotSet)
{
if (firstTileNotSet) firstTitleNotSet = false;
//...
}
That second comparison will likely be optimized by the compiler.
But if you have a preference for a post-increment operator:
int iterationCount = 0;
if (titleChangedSinceLastGet() || iterationCount++ != 0)
{
//...
}
Note that this will be a problem if iterationCount overflows, but the same is true of the bool firstTitleNotSet that you were post-incrementing.
In terms of code readability and maintainability, I would recommend the former. If the logic of your code is sound, you can probably rely on the compiler to do a very good job optimizing it, even if it looks inelegant to you.
That should work:
int firstTitleSet = 0;
if (titleChangedSinceLastGet() || (!firstTitleSet++))
If you wish to avoid overflow you can do:
int b = 1;
if (titleChangedSinceLastGet() || (b=b*2%4))
at the first iteration b=2 while b=0 at the rest of them.
I came across this code written by someone else. Is this usage of the conditional operator recommended or commonly used? I feel it is less maintainable - or is it just me? Is there any alternate way of writing this?
exp_rsp_status = req.security_violation ? (dis_prot_viol_rsp && is_mstr) ?
uvc_pkg::MRSP_OKAY : uvc_pkg::MRSP_PROTVIOL : req.slv_req.size() ?
((is_mst_abort_rsp && dis_mst_abort_rsp) ||
((req.slv_req[0].get_rsp_status()==uvc_pkg::MRSP_PROTVIOL) && dis_prot_viol_rsp) ||
(is_mst_abort_rsp && req.is_pci_config_req() && dis_pcicfg_mst_abort_rsp)) ?
uvc_pkg::MRSP_OKAY : req.slv_req[0].get_rsp_status() : uvc_pkg::MRSP_OKAY;
That's just horrible code.
It's badly formatted. I don't see the hierarchy of the expression.
Even if it had good formatting, the expression would be way too complex to quickly parse with the human eye.
The intention is unclear. What's the purpose of those conditions?
So what can you do?
Use conditional statements (if).
Extract the sub-expressions, and store them in variables. Check this nice example from the refactoring catalog.
Use helper functions. If the logic is complex, use early returns. Nobody likes deep indentation.
Most importantly, give everything a meaningful name. The intention should be clear why something has to be calculated.
And just to be clear: There's nothing wrong with the ternary operator. If used judiously, it often produces code that's easier to digest. Avoid nesting them though. I occasionally use a second level if the code is crystal clear, and even then I use parentheses so my poor brain doesn't have to do extra cycles decyphering the operator precedence.
Care about the readers of your code.
Perhaps this is in a device driver's message loop and the original coder, possibly 10 years ago, didn't want jumps in the code. I hope he verified that his compiler didn't implement the ternary operator with jumps!
Examining the code, my first remark is that a sequence of ternary operators is -- like all code -- better readable when adequately formatted.
That said, I'm not sure that I parsed the OP's example correctly, which speaks against it. Even a traditional nested if-else construct would be hard to verify. This expression violates the fundamental programming paradigm: Divide and Conquer.
req.security_violation
? dis_prot_viol_rsp && is_mstr
? uvc_pkg::MRSP_OKAY
: uvc_pkg::MRSP_PROTVIOL
: req.slv_req.size()
? is_mst_abort_rsp && dis_mst_abort_rsp
|| req.slv_req[0].get_rsp_status()==uvc_pkg::MRSP_PROTVIOL
&& dis_prot_viol_rsp
|| is_mst_abort_rsp && req.is_pci_config_req() && dis_pcicfg_mst_abort_rsp
? uvc_pkg::MRSP_OKAY
: req.slv_req[0].get_rsp_status()
: uvc_pkg::MRSP_OKAY;
I wanted to check how the code looks when refactored. It sure is not shorter but I like how the speaking function names make the intent clearer (of course I guessed here). This is, to some degree, pseudo code because the variable names are probably not global so that the functions would have to have parameters, making the code less clear again. But perhaps the parameter could be a single pointer to a status or request structure or such (from which values like dis_prot_viol_rsp have been extracted). Whether or not to use a ternary when combining the different conditions is up to debate. I find it often elegant.
bool ismStrProtoViol()
{
return dis_prot_viol_rsp && is_mstr;
}
bool isIgnorableAbort()
{
return is_mst_abort_rsp && dis_mst_abort_rsp;
}
bool isIgnorablePciAbort()
{
return is_mst_abort_rsp && req.is_pci_config_req() && dis_pcicfg_mst_abort_rsp;
}
bool isIgnorableProtoViol()
{
return req.slv_req[0].get_rsp_status()==uvc_pkg::MRSP_PROTVIOL && dis_prot_viol_rsp;
}
eStatus getRspStatus()
{
eStatus ret;
if( req.security_violation )
{
ret = ismStrProtoViol() ? uvc_pkg::MRSP_OKAY : uvc_pkg::MRSP_PROTVIOL;
}
else if( req.slv_req.size() )
{
ret = isIgnorableAbort()
|| isIgnorableProtoViol()
|| isIgnorablePciAbort()
? uvc_pkg::MRSP_OKAY
: req.slv_req[0].get_rsp_status();
else
{
ret = uvc_pkg::MRSP_OKAY;
}
return ret;
}
Finally we can exploit the fact that uvc_pkg::MRSP_OKAY is kindof the default and only overwritten under certain circumstances. This eliminates a branch. Look how after some chiseling the code's reasoning is nicely visible: If it's not a security violation look closer and check the actual request status, minus empty requests and ignorable aborts.
eStatus getRspStatus()
{
eStatus ret = uvc_pkg::MRSP_OKAY;
if( req.security_violation )
{
ret = ismStrProtoViol() ? uvc_pkg::MRSP_OKAY : uvc_pkg::MRSP_PROTVIOL;
}
else if( req.slv_req.size()
&& !isIgnorableAbort()
&& !isIgnorableProtoViol()
&& !isIgnorablePciAbort()
)
{
ret = req.slv_req[0].get_rsp_status();
}
return ret;
}
What an ugly mess. I broke it out into if and else's just to see what it was doing. Not much more readable, but thought I'd post it anyways. Hopefully someone else has a more elegant solution for you. But to answer your question, don't use ternaries that complicated. No one wants to do what I just did to figure out what it's doing.
if ( req.security_violation )
{
if ( dis_prot_viol_rsp && is_mstr )
{
exp_rsp_status = uvc_pkg::MRSP_OKAY;
}
else
{
exp_rsp_status = uvc_pkg::MRSP_PROTVIOL;
}
}
else if ( req.slv_req.size() )
{
if ( ( is_mst_abort_rsp && dis_mst_abort_rsp ||
( req.slv_req[0].get_rsp_status() == uvc_pkg::MRSP_PROTVIOL && dis_prot_viol_rsp ) ||
( is_mst_abort_rsp && req.is_pci_config_req() && dis_pcicfg_mst_abort_rsp ) )
{
exp_rsp_status = uvc_pkg::MRSP_OKAY;
}
else
{
exp_rsp_status = req.slv_req[0].get_rsp_status();
}
}
else
{
exp_rsp_status = uvc_pkg::MRSP_OKAY
}
This is terrible code.
While it is often desirable to initialize a variable with a single expression (for example, so we can make it const), this is no excuse to write code like this. You can move the complex logic into a function and call it to initialize the variable.
void
example(const int a, const int b)
{
const auto mything = make_my_thing(a, b);
}
In C++11 and later, you can also use a lambda to initialize a variable.
void
example(const int a, const int b)
{
const auto mything = [a, b](){
if (a == b)
return MyThing {"equal"};
else if (a < b)
return MyThing {"less"};
else if (a > b)
return MyThing {"greater"};
else
throw MyException {"How is this even possible?"};
}();
}
Others already said how awful that code excerpt is, with nice explanations. I will just provide few more reasons why that code is bad :
if you consider one "if-else" to implement exactly one feature, then it is clear how complex that code is. In your case, I can not even count number of ifs.
It is obvious that your code is breaking breaking the single responsibility principle, which tells :
...a class or module should have one, and only one, reason to change.
unit testing that would be a nightmare, which is another red flag. And I bet that your colleague didn't even try to write unit tests for that piece of code.
Common or recommended? No.
I did something similar, but I had my reasons:
It was an argument into a third-party C function.
I was not well versed in modern C++ at the time.
I commented and formatted the f*** out of it because I knew SOMEONE besides me was going to read it...or I needed to know what it was doing years later.
It was DEBUG CODE that was never going into a release.
textprintf_ex(gw->GetBackBuffer(), font, 0, 16, WHITE, -1, "BUTTON: %s",
//If... Then Display...
(ButtonClicked(Buttons[STOP]) ? "STOP"
: (ButtonClicked(Buttons[AUTO]) ? "AUTO"
: (ButtonClicked(Buttons[TICK]) ? "TICK"
: (ButtonClicked(Buttons[BLOCK]) ? "BLOCK"
: (ButtonClicked(Buttons[BOAT]) ? "BOAT"
: (ButtonClicked(Buttons[BLINKER]) ? "BLINKER"
: (ButtonClicked(Buttons[GLIDER]) ? "GLIDER"
: (ButtonClicked(Buttons[SHIP]) ? "SHIP"
: (ButtonClicked(Buttons[GUN]) ? "GUN"
: (ButtonClicked(Buttons[PULSAR]) ? "PULSAR"
: (ButtonClicked(Buttons[RESET]) ? "RESET"
: /*Nothing was clicked*/ "NONE"
)))))))))))
);
The only reason I did not use an if-else chain was it would have made the code immense and harder to follow because all I needed to do was print a word to the screen.
A part of my program (I can add more details if necessary) contains this line:
if((e->start->explored = false) || (e->end->explored = false)){
//do action...
}
This is part of a graph algorithm, where e is a directed edge with incident vertices "start" and "end." I would like the 'action' to happen if at least one of the incident vertices of e is unexplored, but this logic appears to be faulty. Although I used a small example and verified that, indeed, the start and end vertices of my edges were unexplored to start with, my overall function is going into an infinite loop.
So then I tested it like this:
if((e->start->explored = false) || (e->end->explored = false)){
//do action...
}
else cout << "FAIL";
...and, of course, it printed a screen of "FAIL." What is my logic error here?
You're assigning false to your properties instead of testing them against false. This is a mistake often made, and quite hard to debug. Change your = assignment operator to the equality operator ==:
if((e->start->explored == false) || (e->end->explored == false)) {
// Do action...
} else {
cout << "FAIL";
}
Instead of comparing the values to false, it's clearer to use the ! not operator instead. The inner brackets are done away with, too:
if(!e->start->explored || !e->end->explored) {
// Do action...
} else {
cout << "FAIL";
}
As the others have expounded you accidentally used assignment instead of comparison. However, the real solution is not to compare at all:
Comparing bool values to literals true and false is nonsensical!
Instead, write:
if(! e->start->explored || ! e->end->explored)
You have used the assignment operator = not the comparison operator ==.
You are assigning values here:
if((e->start->explored = false) || (e->end->explored = false)){
Should be:
if((e->start->explored == false) || (e->end->explored == false)){