I read some legacy code:
if ( 1 || !Foo() )
Is there any seen reason why not to write:
if ( !Foo() )
The two are not the same. The first will never evaluate Foo() because the 1 short-circuits the ||.
Why it's done - probably someone wanted to force entry in the then branch for debugging purposes and left it there. It could also be that this was written before source control, so they didn't want the code to be lost, rather just bypassed for now.
if (1 || !Foo() ) will be always satisfied. !Foo() will not even be reached because of short-circuits evaluation.
This happens when you want to make sure that the code below the if will be executed, but you don't want to remove the real condition in it, probably for debug purposes.
Additional information that might help you:
if(a && b) - if a is false, b won't be checked.
if(a && b) - if a is true, b will be checked, because if it's false, the expression will be false.
if(a || b) - if a is true, b won't be checked, because this is true anyway.
if(a || b) - if a is false, b will be checked, because if b is true then it'll be true.
It's highly recommended to have a macro for this purpose, say DEBUG_ON 1, that will make it easier to understand what the programmer means, and not to have magic numbers in the code (Thanks #grigeshchauhan).
1 || condition
is always true, regardless whether the condition is true or not. In this case, the condition is never even being evaluated. The following code:
int c = 5;
if (1 || c++){}
printf("%d", c);
outputs 5 since c is never incremented, however if you changed 1 to 0, the c++ would be actually called, making the output 6.
A usual practical usage of this is in the situation when you want to test some piece of code that is being invoked when the condition that evaluates to true only seldom is met:
if (1 || condition ) {
// code I want to test
}
This way condition will never be evaluated and therefore // code I want to test always invoked. However it is definitely not the same as:
if (condition) { ...
which is a statement where condition will actually be evaluated (and in your case Foo will be called)
The question was answered properly - the difference is the right side of the or operation is short-circuited, suggesting this is debug code to force entry into the if block.
But in the interest of best practices, at least my rough stab at a best practice, I'd suggest alternatives, in order of increasing preference (best is last):
note: noticed after I coded examples this was a C++ question, examples are C#. Hopefully you can translate. If anyone needs me to, just post a comment.
In-line comment:
if (1 /*condition*/) //temporary debug
Out-of-line comment:
//if(condition)
if(true) //temporary debug
Name-Indicative Function
//in some general-use container
bool ForceConditionForDebug(bool forcedResult, string IgnoredResult)
{
#if DEBUG
Debug.WriteLine(
string.Format(
"Conditional {0} forced to {1} for debug purposes",
IgnoredResult,
forcedResult));
return forcedResult;
#else
#if ALLOW_DEBUG_CODE_IN_RELEASE
return forcedResult;
#else
throw new ApplicationException("Debug code detected in release mode");
#endif
#endif
}
//Where used
if(ForceConditionForDebug(true, "condition"))...
//Our case
if(ForceConditionForDebug(true, "!Foo()"))...
And if you wanted a really robust solution, you could add a repository rule to source control to reject any checked in code that called ForceConditionForDebug. This code should never have been written that way because it obviously doesn't communicate intent. It never should have been checked in (or have been allowed to be checked in) (source control? peer review?) And it should definitely never be allowed to execute in production in its current form.
Related
This question already has answers here:
Is returning early from a function more elegant than an if statement?
(14 answers)
Closed 7 years ago.
I have been referring my new company's code, where I found the code was not wrapped around IF and ELSE so was little bit confusing in flow. For example:
if(user_is_registered)
{
// You are already registered.
//exit
}
//New user's registration code goes here
While my last company was following the other way i.e. :
if(user_is_registered)
{
// You are already registered.
}
else
{
//New user's registration code goes here
}
Like every fresher I am confused which is the best practice to follow with legitimate reasons. Please enlighten me. I tried to find out answers for the same, but could not get. Some of answers are there in which some experts are supporting way 1 some are supporting way 2. Please also suggest me other refs if available. Thank you.
It may well have been a decision made in order to avoid nesting. In your example it's not immediately apparent, but if there are further IF, LOOP, etc. statements further down in the registration logic, then nesting start to occur.
As a general rule nesting should be avoided and refactored away as it hinders comprehension and is often indicative that the method is doing too much.
e.g.
if ( user_is_registered )
{
// do something & return
}
else
{
// do something else
if ( some_other_condition )
{
// do another thing
while (something_is_not_true)
{
// loopy things
}
}
}
When you use an else you're building logic that is very explicit. By having separate if statements you can apply multiple blocks of rules on given conditions.
It could be that the object being compared meets multiple requirements, so Else would not be any good.
Take this example:
var x = 10;
if (x < 11){
// do something
// - this gets hit
}else{
// do something else
}
// perhaps i want to have multiple conditions that x meets..
if (x < 11){
// do something
// - this gets hit
}
if {x == 10){
// do something
// - this gets hit - provided the if before didn't make changes to X
}
if (x != 10){
// do something - this won't be hit, unless a previous if made changes to x
}
Now - when you take your particular example, //New user's registration code goes here in your first block will ALWAYS fire if there wasn't a way to exit out of the method, as there is in your if. In your 2nd block it only fires if the if doesn't match.
Personally, I would wrap in the if/else, in this case and be explicit with the code and the intent.
If you want a block of code to be executed only if the condition in if statement fails, then add the block as else part of the if statement. The statements are exclusive. Only the if block or else block is executed not both.
If you want the block of code to be always executed, include the block after if statement. The block is always executed.
This question already has answers here:
What is the difference between these (bCondition == NULL) and (NULL==bCondition)? [duplicate]
(6 answers)
Closed 9 years ago.
I have received code from someone working earlier on it, and it contains a lot of lines like
while(false==find && false == err && k<kmax)
if(true==refract(ep1,ep2,n1,RI_blood, RI_collagen))
and my favorite line is
if(false == (ret_s<0))
The other code is done really well, documented just fine, but these lines with these odd conditions are throwing me off, and I wonder why they are done that way.
Especially that false==(ret_s<0) is completely confusing, and you kind of need to read that line like three times to understand what they want there.
Is this a common programming style, don't I understand the reasoning for that, or is that just bad style?
Edit: I don't feel this is similar to if(object==NULL) vs if(NULL==object), since this isn't about accidental assigning but about obfuscated if clauses...
Is this a common programming style?
No.
don't I understand the reasoning for that?
Some people like to explicitly compare booleans with true or false, even though the result is exactly the same boolean value. The logic is presumably that, by making the code harder to read and more surprising, people will think harder about it and make fewer assumptions about its behaviour. Or perhaps just that code should be hard to maintain, since it was hard to write.
Others like to write comparisons with constants backwards, which prevents mistakes like if (x = 5) when you meant if (x == 5). Any modern compiler will warn you about this mistake, so again its only real purpose is to make the code harder to read.
Combining these two behaviours gives the bizarre code you posted.
Or is that just bad style?
It's a style. I'm no judge of style, but if you like to keep maintainence programmers on their toes, it certainly does that. Personally, I like my code to be readable, but that's just me.
my favorite line is
I once encountered return a && !b implemented in about ten lines of code. The first line was switch(a).
Yoda Conditions
Using if(constant == variable) instead of if(variable == constant), like if(4 == foo). Because it's like saying "if blue is the sky" or "if tall is the man".
Its a safe guard against assignment in C++.
In C++ it is perfectly legal to do this
if (foo = true) ....
In this case the single = is an assignment and would replace the value of foo.
This is not legal and will generate a compiler error
if (true = foo) ....
Constants and literals are often put on the left because it prevents accidental assignments. Consider typing:
if(foo == bar)
as:
if(foo = bar)
The second might appear to work... but silently clobber foo. If foo is a constant, this error is not longer possible.
It's a self-protection technique that prevents you from accidentally typing an assignment operator (=) instead of equality operator (==), which can introduce strange bugs. Putting the constant value on the left hand side will introduce a compiler error, while putting a variable on the LHS will just silently compile.
Perhaps the original programmer thought that explicit comparison to true or false was clearler than if(condition) or if(!condition) and coded things in that way. I haven't seen this particular style before however.
It's quite subjective but I find while(!find && !err && k<kmax) easier to read.
The code could have been written for a shop where there is a site standard that every conditional statement must include a comparison operator, in order to avoid accidentally leaving out part of the comparison. (Maybe that's a stretch, but you did say that the rest of the code was very good.) That, coupled with a standard or habit of putting the constant on the left to avoid accidentally using = instead of == would give pretty much the code you showed. It doesn't explain the use of 'false' instead of the more natural 'true', though. Maybe it's a (misguided on multiple levels) attempt to gain microefficiency by comparing to zero instead of 1 at the machine level.
for my is only bad style,
if(false == (ret_s<0))
is equals to in C#
if(!(ret_s<0))
When I compile C++ code with Visual C++ 9 with "warning level 4" the following:
while( true ) {
//loop body with break on certain condition
}
and the following:
for( ; true; ) {
//same loop body
}
both trigger C4127: conditional expression is constant warning but the following:
for( ; ; ) {
//same loop body
}
compiles without warning.
Why this difference, especially between the second and the third variant?
The reason for warning the user of constant conditional expressions is to help avoid bugs where the expression ends up being constant (for example, due to a typo). In the last case, there is no expression, so there is no risk of it accidentally being constant.
The reason is simple, though stupid.
It is important to diagnose infinite loop, but such might not be evident:
while(i >= 0) { --i; } // infinite if i unsigned
while(SOME_MACRO(i)) // err, depends on the expansion of macros
It is a great feature of a compiler to produce a warning for a tautological test, that is a test that turns out to be either always true or always false, because it's not obvious when it comes from a macro expansion or within a dependent context.
It just seems that VC++ pushed a bit too far here, and instead of considering tautological conditions warns for all true or false conditions it can find, even when they are already clearly stated in the code.
The for ( ;; ) construct is the canonical way to intentionally code an "endless" loop. I could imagine the compiler designers didn't want to generate a warning for that.
No point. After all, the langauge specification says ($6.5.3/2),
Either or both of the condition and
the expression can be omitted. A
missing condition makes the implied
while clause equivalent to
while(true).
So for ( ; ; ) is equivalent to while(true) even according to the Standard. Therefore, I don't see any reason why the compiler should give warning in one case but not in the other!
--
If the compiler decides to give warning, then in my opinion, the compiler should give warning when the condition is missing as opposed to when it's present, so that the warning would be interpreted as hint for programmer to mention his intention clearly and explicitly.
I mean, for ( ;; ) is more likely to be a typo than the explicit mention of condition in for ( ;true; ). The latter tells programmer's clear and explicit intent. As Steve says in comment:
For an int value y, char x = y is
equivalent to char x = (char)y, but
you might want a warning for an
implicit narrowing conversion on the
first but not the second.
So explicit intention should not receive warning, while implicit intention should receive!
Compiler warning are here to help catch potential bugs. Using an always true condition in a while loop is probably an error. For exemple, in the following code, this is probably a bug, and I'd like the compiler to warn me about it:
unsigned int x;
// ...
while (x >= 0) {
// ...
}
In such a situation, in optimized build the compiler will probably deduce that the condition is always true (since an unsigned integer cannot be smaller than 0). So there is a need for detection of an always true condition in while loop. I think that whoever wrote the detection of such an error didn't special case the while (true) case, as there is a simple way to do a infinite loop with for (;;).
You can read here, how the decision to add a warning or not in Visual Studio, is taken (the exemple are about C# but I suppose that the team has the same rule of thumb for warning in C++).
I'm reviewing a quite old project and see code like this for the second time already (C++ - like pseudocode):
if( conditionA && conditionB ) {
actionA();
actionB();
} else {
if( conditionA ) {
actionA();
}
if( conditionB ) {
actionB();
}
}
in this code conditionA evaluates to the same result on both computations and the same goes for conditionB. So the code is equivalent to just:
if( conditionA ) {
actionA();
}
if( conditionB ) {
actionB();
}
So the former variant is just twice more code for the same effect. How could such manner (I mean the former variant) of writing code be called?
This is indeed bad coding practice, but be warned that if condition A and B evaluations have any side effects (var increments, etc.) the two fragments are not equivalent.
I would call it bad code. Though I've tended to find similar constructs in project that grew without any code review being done. (Or other lax development practices).
Guys? Look at this part: ( conditionA && conditionB )
Basically, if conditionA happens to be false, then it won't evaluate conditionB.
Now, it would be a bad coding style but if conditionA and conditionB aren't just evaluating data but if there's also some code behind these conditions that change data, there could be a huge difference between both notations!
if conditionA is false then conditionA is evaluated twice and conditionB is evaluated just once.
If conditionA is true and conditionB is false, then both conditions are evaluated twice.
If both conditions are true, both are executed just once.
In the second suggestion, both conditions are executed just once... Thus, these methods are only equivalent if both methods evaluate to true.
To make things more complex, if conditionB is false then actionA could change something that would change this validation! Thus the else branch would then execute actionB too. But if both conditions evaluates to true and actionA would change the evaluation of conditionB to false, it would still execute actionB.
I tend to refer to this kind of code as: "Why make things easy when you can do it the hard way?" and consider this a design pattern. Actually, it's "Mortgage-Driven development" where code is made more complex so the main developer will be the only one to understand it, while other developers will just become confused and hopefully give up to redesign the whole thing. As a result, the original developer is required to stay just to maintain this code, which is called "Job security" and thus be able to pay his mortgage for many, many years.I wonder why something like this would be used, then realized that I use a similar structure in my own code. Similar, but not the same:
if (A&&B){
action1;
} elseif(A){
action2;
} elseif(B){
action3;
} else{action4}
In this case, every action would be the display of a different message. A message that could not be generated by just concatenating two strings. Say, it's a part of a game and A checks if you have enough energy while B checks if you have enough mass. Of you don't have enough mass AND energy, you can't build anything anymore and a critical warning needs to be displayed. If you only have energy, a warning that you have to find more mass would be enough. With only energy, your builders would need to recharge. And with both you can continue to build. Four different actions, thus this weird construction.
However, the sample in the Q shows something completely different. Basically, you'd get one message that you're out of mass and another that you're out of energy. These two messages aren't combined into a single message.
Now, in the example, if conditionA would detect energy levels and conditionB would detect mass levels then both solution would just work fine. Now, if actionA tells your builders to drop their mass and start recharging, you'd suddenly gain a little bit of mass again in your game. But if conditionB indicated that you ran out of mass, that would not be true anymore! Simply because actionA released mass again. if actionB would be the command to tell builders to start collecting mass as soon as they're able then the first solution will give all builders this command and they would start collecting mass first, then they would continue their other actions. In the second solution, no such command would be given. The builders are recharged again and start using the little mass that was just released. If this check is done every 5 minutes then those builders would e.g. recharge in one minute to be idle for 4 more minutes because they ran out of mass. In the first solution, they would immediately start collecting mass.
Yeah, it's a stupid example. Been playing Supreme Commander again. :-) Just wanted to come up with a possible scenario, but it could be improved a lot!...
It's code written by someone who doesn't know how to use a Karnaugh Map.
This is very close to the 'fizzbuzz' Design Pattern:
if( fizz && buzz ) {
printFizz();
printBuzz();
} else {
if( fizz ) {
printFizz();
}
else if( buzz ) {
printBuzz();
}
else {
printValue();
}
}
Maybe the code started life as an instance of fizzbuzz (maybe copied-n-pasted), then was refactored slightly into what you see today due to slightly different requirements, but the refactoring didn't go as far as it probably should have (boolean logic can sometimes be a bit trickier than one might think - hence fizzbuzz as an interview weed-out technique).
I would call it bad code too.
There is no best way on indenting, but there is one golden rule : choose one and stick with it.
This is "redundant" code, and yes it is bad. If some precondition must be added to the calls to actionA (assuming that the precondition can't be put into actionA itself), we now have to modify the code in 2 places, and therefore run the risk of overlooking one of them.
This is one of those times where you can feel better about deleting some lines of code, than in writing new ones.
inefficient code?
Also, could be called Paid per line
I would call it 'twice is better'. It's made like that to be sure that the runtime really understood the question ;).
(although in multi-threaded, not-safe environment, the result may differ between the two variants.)
I might call it "code I wrote last month while I was in a hurry / not focused / tired". It happens, we all make or have made these kind of mistakes. Just change it. If you want to you can try and find out who did this, hope it is not you, and give him/her feedback.
Since you said you've seen this more than once, it seems that it's more than a one-time error due to being tired. I see several reasons for someone to repeatedly come up with such code:
The code was originally different, got refactored, but whoever did this oversaw that this is redundant.
Whoever did this didn't have a good grasp of boolean logic.
(Also, there's the slight possibility that there might be more to this than what your simplified snipped shows.)
As pgast has said in a comment there is nothing wrong with this code if actionA effects conditionB (note that this is not a condition with a side effect but an action with a side effect (which you kind of expect))
Can this ever happen ?
3 asserts, where one should activate.
int nr = perform_calc();
assert( nr == 0);
assert( nr > 0);
assert( nr < 0);
Can there be a case when the program doesn't activate the asserts on g++ 3.4.4.
And no I don't have the possibility to change the code in order to print the number out in case the asserts don't activate.
Any ideas?
Edit: After reading several comments I was forced to edit. Show the code? why are you doing this stupid thing ? I don't believe it ! Where is it used ?
From my question it should have been obvious that I will not post/change the code because of several possible reasons:
I'm a total beginner and is ashamed of the code (no crime there, sure it makes answering to the question much easier if I did post it)
I was asked to help out a friend with only little information (and no I did not ask him why can't you check the number returned, or why can't he just add a breakpoint).
I am writing my code in emacs without any compiler and is sending it to a remote server that compiles it, runs it and only can return failed asserts if something goes wrong.
If you believed that I was making a prank or a hoax you should have voted for a closure of the thread instead. I would have been perfectly fine with that. But adding unnecessary comments like this only made me want an "attitude" flag to be implemented.
I want to thank others for their comments and answers that actually tried to explain and answered my question.
assert is unchecked if the macro NDEBUG is defined. Make sure you #undef NDEBUG when compiling this translation unit.
You can invoke gcc with the -E switch to verify that your assert statements are still in the code.
As I've seen so ugly things in my life, it could be explained if perform_calc() has a buffer overrun that overwrites the return address in the stack. When the function ends, the overwritten address is recovered from the stack and set to the current PC, leading to a jump maybe in another area of the program, apparently past the assertion calls.
Although this is a very remote possibility, so it's what you are showing.
Another possibility is that someone did an ugly macro trick. check if you have things like
#define assert
or some colleague put something like this in a header while you were at the restroom
#define < ==
#define > ==
As suggested in another answer, check with gcc -E to see what code is actually compiled.
It doesn't look like that code is correct in the first place. If debugging is on (DEBUG and/or _DEBUG are set and NDEBUG is unset):
assert( nr == 0);
The above line will call exit() if nr != 0. Therefore, if this line passes, the second assert will execute:
assert( nr > 0);
... And call exit() because nr == 0 and !(nr > 0).
assert( nr < 0);
And this third line will never run at all.
What, precisely, is the point of this code? And why, if these asserts could be added, could you not instead add a printf()?
Is this code multithreaded? Maybe you have a race condition.
And no I dont have the possibility to
change the code in order to print the
number out..
Strange. You obviously have the ability to insert the assert() statements, because if they were actually in real code you couldn't touch, the code could not possibly work. So why can't you print the value the assert() calls test?
I suspect you've accidentally eliminated the problem while sanitizing the code fragment. There's either more code (and nr is getting changed between asserts) or it doesn't actually look like that (or, per rlbond, you don't have assert turned on).
Try posting a less sanitized code segment, and let's see if we can't work it out.
Could it be a NaN? In that case, the following assert would fail:
assert( nr == nr );