Java Nested If condition - java

I suddenly got a strange doubt..
I want to know whether
if(a && b) {
}
is same as
if(a) {
if(b) {
}
}
or not..
Both the cases giving me the same result. But, I'm still not feeling comfort to use the first method in my project.
Any helps??

If using If-else statement then
if loop will execute only condition is true:---
if(condition){
//execute when it is true
}
In your case you are using Two variable a and b with AND OPERATOR.
The property of AND OPERATOR is If All giving value is true then it will return true otherwise false.
If you want to use your method then
/*
check for your in a and b
both are true
*/
then your method will be execdute
if(a && b) {
//if a and b both return true(a=true,b=true)
}

It is same. In the first case compiler guarantees that second condition will not be executed if first condition returns false.

Yes they are the same as far as functionality is concerned. && is a short-circuit operator. So, in a && b, b will be evaluated only if a is evaluated to true.
Same is the case with nested if. The inner if will be executed only when outer if is evaluated to true. But the 1st one shows your intents better if you want to execute the code only when both a and b are true.
But, one difference is that, you can implement the functionality of a = true, b = false, in 2nd case by adding that functionality before the nested if starts. But, you can't do that in 1st

a && b means if a is tue and so is b, so:
if(a && b) {
}
does not leave space for indecision, it's all or nothing, only if a && b the if body will be executed, while
if(a) {
if(b) {
}
}
leaves you space to act if a, without considering b for the moment. So if you want to do some actions before checking b you can.
If you do not have anything to do just when a then the two are equal and imho the first is to prefer because it is more readable.

Yes, it's the same thing. The && operator checks if both conditions are true. If you nest your if statements like that, it amounts to the same thing since the second one will only be checked if the first one is true. Only separate them if you need something done that involves a being true but not b.

In both cases It's just short-circuiting.
in which the second argument is only executed or evaluated if the first argument does not suffice to determine the value of the expression:
The short-circuit expression x Sand y (using Sand to denote the short-circuit variety) is equivalent to the conditional expression if x then y else false; the expression x Sor y is equivalent to if x then true else y.
Coming to the syntax,The first thing (if(a && b) )which beautifies your code and and more readable.

Both conditions are same as in first one: if(a && b){ }, you are checking with && operator So, in a && b, b will be evaluated only if a is evaluated to true.
while in second case, first of all it will check value of a in outer if condition and if it satisfies then it will check value of b in inner if condition.
But fist one is more preferable.

As many have stated before me: they are technically equivalent (right down to the short-circuit semantics).
But I dare say the && operator is preferred in any situation, and that it's not just a matter of taste. The nested if is harder to read in day-to-day code with more than just control statements, and leaves more room for error.
Mostly because if(b) communicates: "the following block is only executed if b is true".
But that's not what happens! The block is only executed if a and b are true (which is exactly what the first method communicates rather elegantly). It's very easy to unintentionally pull it out of the if(a) context (any IDE has plenty of ways to shuffle code around) and create a bug.
The nested if also leaves a lot of room for horrible code later on. Wedging code between the inner and outer can make it tricky to understand which code is executed when - especially if a and b are complex expressions. And things become really nasty when somebody decides to toss in a few else-statements.. :-) There's simply no way to get into that mess with a single && operator.
Some might argue this "flexibility" is a reason to use the second method, but I'd argue there is almost always a way to rewrite that cleanly using explicit conditions. Coding is hard enough without spending all your brain cycles on control logic.
Bottom line: every Java programmer understands the semantics of the conditional-AND operator. Relying on built-in language constructs instead of rolling your own equivalents goes a long way towards maintainability and correctness.
Hope this helps.

Related

unreachable code when trying to stop executing method if condition true [duplicate]

Today, after half an hour of searching for a bug, I discovered that it is possible to put a semicolon after an if statement instead of code, like this:
if(a == b);
// Do stuff
Which basically means that the stuff will be done whether a equals b or not, and the if statement has no point whatsoever. Why doesn't Java give me an error? Is there any situation in which this would be useful?
Why does it happen?
Java Language Specification says that:
The Empty Statement
An empty statement does nothing.
EmptyStatement:
;
Execution of an empty statement always completes normally
It essentially means that you want to execute empty statement if a==b
if(a == b);
What should you do:
There are two main solutions to this problem:
You can avoid problems with empty statement by using code formatter
and surrounding stuff inside if with { and }. By doing this
Your empty statement will be much more readable.
if(a == b){
;
}
You can also check tools used for static code analysis such as:
Findbugs
Checkstyle
Pmd
They can instantly highlight problems such as this one.
I would recommend to combine both solutions.
Is there any situation in which this would be useful?
Useful? As in "makes your code cleaner, clearer, faster, more maintainable"? Not at all. This is most likely poor, confusing code.
But it's not necessarily benign. Such a statement can perform actions and/or alter state due to methods which cause side effects, and optionally evaluate those methods due to short-circuiting of operators.
if( a() && b() );
Here, a() or b() may do something, and b() will only execute if a() is true.
As to why, I think the answer is simply that it would be worse to deviate from defined, expected behavior (e.g. statements like while(reader.read());) than the alternative of developers writing bad code.
Writing bad code is always possible. And just to reiterate, this would be bad code in almost any case.
A possible use case:
if (a==b);
else {
// Do something
}
Not good, but possible.
Still, I do think that the Java specification should disallow an empty if.
If you're using Eclipse, you can make it warn you about those statements:
If you use an if statement, the first statement after the if will be executed if the condition is true. If you have a block after the if (with curly braces), it counts for that whole block. If there is no block it counts for only one statement. A single semicolon is an empty statement. You could also write the code from you example like this:
if(a==b) {
;
}
It is an old leftover from the days when there was more syntactic sugar to differentiate expressions from statements.
Basically, the comma was used as the list item separator, so the semicolon was used as the "list of statements" separator. The downside is in the handling of null items in lists, and null statements in blocks.
In a list of items, Java uses the explicit keyword null, but a "null statement" is just an empty line. Allowing the existence of an empty line is a holdover from tradition inherited from C.
Why do it? Especially with an if statement when you know that no statements are being executed: Because some if statements have side effects:
int c;
if ((c = in.read()) != -1);
Yes, it is not the best example, but basically it says read a byte from the stream and do nothing. Might be useful in some corner cases, but even if this example isn't the best, it illustrates the intent. We want to feel the side-effects of the expression without accidentally executing any statements.
I can't think of an occasion where it is useful. It can be useful for loops like
while(do something);
or
for(init; do something; something else);
If you use your code formatting in your IDE regularly these sort of bugs become obvious. Some IDEs highlight this as a probable bug as well.
I'd agree with you there's no useful purpose to this for a human. I suspect it's there because it simplifies the language definition; it means that the thing that comes after an if is e same as the thing that comes after a while, for instance.
Why? It's because its easier for compiler writers. You don't have to make a special case to check for semicolons after if(cond) and has an added usage of allowing
if (cond && maybeFunc())
;// Code here I want to ignore
Even though it's actually a terrible idea to allow this. It's just easier to allow and then to add a case to check this.
Java allows an empty block any place a statement block is allowed. I am sure making this a general rule for all blocks simplifies the compiler.
I agree that this is primarily the cause of bugs that are spectacularly hard to find. I always use braces around blocks, even when there is a single statement, but Java allows you to make a block with braces at any point, so using braces can not save you from this fate. For example, I once wasted 4 hours trying find something like this:
while (condition);
{
statement;
statement;
}
The semicolon at the end of the first line was a typo, accidentally making the statement block for the while loop empty. Because the syntax is valid the program compiled and ran fine, just not the way I wanted it to. It was really hard to find.
I can think of one situation where it is very nice that you are allowed to have empty blocks, and this is something like this:
if (condition1) {
do_action_1();
}
else if (condition2) {
//nothing really to do in this case
}
else if (condition3) {
do_action2();
}
else {
do_action3();
}
In the above example, you want to be able to separate out various conditions. Remember, those conditions might be overlapping, so it is not always possible to rearrange the order. If one of the conditions really does not need anything done, then it is nice that Java allows you to have an empty block. Otherwise, the language would need some form of a "noop" method to use when you really do not want anything done.
I personally would prefer the explicit "noop" statement -- but that is not how Java is defined.
Just a FYI about the usability and what difference it makes or can make if there is a statement like that
Consider a piece of code like the following.
int a = 10;
if ((a = 50) == 50);
System.out.println("Value of a = " + a);
Clearly in this case, the if statement does change the output. So a statement like that can make a difference.
This is a situation where this could be useful or better to say have an impact on program.
if(a==b)
println("a equals b");
You can use an IF statement without {} if there is only a single line to be executed, so by using if(a==b); you are saying if they equal, execute and empty statement... So it will do nothing, and then return to your normal loop, outside of the IF block.
A few definitions from the jls explain this (chapter 14):
Blocks are Statements
As stated here, a Block is a StatementWithoutTrailingSubstatement, which in turn is a StatementNoShortIf, which is a Statement. Thus where ever any of these is required, we can insert a Block.
The if-clause
Though this is as well the case for for and while-loops, I'll use if-statements. These rules are pretty much the same. The syntactical description of if-statements can be found here.
IfThenStatement:
if ( Expression ) Statement
IfThenElseStatement:
if ( Expression ) StatementNoShortIf else Statement
IfThenElseStatementNoShortIf:
if ( Expression ) StatementNoShortIf else StatementNoShortIf
So we can use our block here.
But why does it work with ; ?
; is defined as the EmptyStatement (link), which is as well a StatementNoShortIf. So in conditional pieces of code, like if-statement and loops, we can replace a Block with a EmptyStatement, if a StatementNoShortIf or Statement is required.
Thus if(Expression)EmptyStatement works.
Why doesn't this give an error?
Pretty simple: java gives an error if it finds invalid syntax. But if(Expression)EmptyStatement is perfectly valid syntax. Instead javac gives a warning if launched with the proper parameters. The full list of warnings that can be dis-/enabled lists the warning-name empty for this purpose. So compilation with -Xlint:all or -Xlint:empty will generate a warning about this.
Your IDE should have an option to enable this kind of warning as well.
For eclipse, see #nullptr's answer. In IntelliJ, you can press Ctrl + Shift + A, enter empty body into the search field and enable the warning (marked in the image)
What is this even used for?
To be honest, there's not much use in it from a minimalistic point of view. There's usually a way to get things done without a "do nothing" command. It's rather a question of personal preferences, whether you rather use
if( a() && b() );
or
if( a() ) b();
and same would apply to other cases, in which the EmptyStatement is used. An important point to consider on this topic is readability of code. There are occasions, where code becomes more readable by using the no-op. On the other hand there are cases, where code becomes quite a lot harder to comprehend with using the EmptyStatement - the above example would count to the later IMO.
I can think of a scenario where an empty statement is required (not for if condition but for while loop).
When a program just want an explicit confirmation from the user to proceed. This may be required when the work after the user confirmation depends on some other things and user want to take control of when to proceed.
System.out.println("Enter Y to proceed. Waiting...");
System.out.println("");
while(!(new Scanner(System.in).next().equalsIgnoreCase("Y")));
System.out.println("Proceeding...");
// do the work here
look this:
int a,b,c = 0;
if(a == b){
c =1;
}
System.out.print(c);//1
so, you can write like this:
if (a == b)c=1;
but,if this code is this:
int a,b,c=0;
if (a != b){
}
if (a == b ){
c =1;
}
you can write like this:
if(a != b);
if(a == b )c=1;
so,you will know if(a != b); do noting
The semi-colon in the if indicates the termination of the if condition as in java ; is treated as the end of a statement, so the statement after if gets executed.
Semicolon at the end of,
if(a==b); simply finish the statement in single line which means ignore the result of condition and continue the execution from the next line
This code is useful, on the other hand sometime introduce bug in program, for example,
case 1.
a = 5;
b = 3;
if(a == b);
prinf("a and b are equal");
case 2.
a = 5;
b = 5;
if(a == b);
prinf("a and b are equal");
would print the same output on the screen...
While working on a programming assignment for class where I am working with a N by N grid of doodads and comparing characteristics of a random doodad to those above, below, left, and right, I found a nice use of this to prevent nested statements and potential boundary exceptions. My goal was to minimize code and keep from nesting if-statements.
if (row == 0);
else (method (grid[row][col], grid[row-1][col]));
if (row == N-1);
else (method (grid[row][col], grid[row+1][col]));
if (col == 0);
else (method (grid[row][col], grid[row][col-1]));
if (col == N-1);<br>
else (method (grid[row][col], grid[row][col+1]));
where method(Doodad a, Doodad b) does some operation between a and b.
Alternatively, you could use exception handling to avoid this syntax, but it works and works well for my application.

Do if statements that call methods on an object modify the object?

I'm trying to perform actions on my object, but only do so if certain things are true. I have several methods which is consider "action" methods, they do some action that attempts to modify the object and returns true/false if that action can be done.
Example 1
Thing thing = new Thing();
if (thing.changeSomething()){
if (thing.shouldDoSomething()){
//do more things
}
}
I know about compound boolean expressions like to check if a number in a valid range of values
if(number>0 && number<=10)
//number is valid
But haven't really done much when the sub-expressions are method calls
Example 2
if ( thing.changeSomething() && (thing.shouldDoSomething() ){
//do more things
}
Is Example 2 the same as Example 1?
Will Example 2 call the shouldDoSomething() method? Because I don't want this to happen because sometimes shouldDoSomething() actually has other implications & changes other aspects of the object.
Calling
if (thing.changeSomething()){
if (thing.shouldDoSomething()){
is esentially equivalent to
if (thing.changeSomething() && thing.shouldDoSomething()){
I guess they are translated to the exact same IL.
However as mentioned in the comments the second method is only executed if the first one evaluates to true. If the first operand of an &&-operator is already false there´s no need to execute the second also, so your shouldDoSomething-method isn´t executed if changeSomething allready returned false.
Btw. this applies to both Java and C#.
In Java, the logical AND operator && is a short circuit operator, meaning the right side is not evaluated if the result of the expression can be determined solely from the left operand. Specifically, if the left side evaluates to false, the whole expression is false and the right side does not need to be evaluated to determine that.
In the case of your function calls:
if ( thing.changeSomething() && (thing.shouldDoSomething() ){
//do more things
}
If thing.changeSomething() returns false then thing.shouldDoSomething() will not be called since the expression evaluates to false regardless of what this function may return. So yes, the above is equivalent to:
if ( thing.changeSomething() ) {
if (thing.shouldDoSomething() ){
//do more things
}
}
The simple answer and what it comes down to is, it depends on if the thing.changeSomething() method returns a boolean. It is going to create problems if it does not. It is very possible to define this method to do something and return true after it does what it was supposed to do. In which case the second example would work.
If it does not return boolean you should see an error or it might not work to your liking.
It should call the method when to do it that way in example 2. What I would recommend because you don't want that is to create getter() and checker() methods that you use to get info on the object without having to change it. This can also be done with data fields, depends on class structure.
Hope this is more digestible and helps!

Is there any reason for Eclipse showing assignment variables in while loops as valid?

I've been punked numerous times while working on Java in eclipse when I write a while loop like so:
while (recsFinished = true)
When in reality I wanted
while (recsFinished == true)
It's a pretty simple mistake, but it happens to me a lot and it totally throws off the program. And the reason it does is because Eclipse doesn't even throw up a warning when I write the assignment as opposed to the equality equation. This leads me to believe there has to be some reason for a while loop with an assignment equation to exist, but why? I can't think of a single use!
Such assignments are popular in C and C++ (particularly within if statments) and have found themselves part of Java too.
Some folk put the literal on the left hand side: while (true == recsFinished) instead and I'm tempted to suggest that you adopt this programming style only that I personally find it obfuscating. This will issue a compiler error if = is used by accident.
Note well though that comparison to true is redundant. Drop it entirely and use while (recsFinished) instead.
It compiles, since it's valid Java syntax.
It's equivalent to :
recsFinished = true;
while (recsFinished) {
....
recsFinished = true;
}
Which is equivalent to
recsFinished = true;
while (true) {
....
recsFinished = true;
}
which would give you an infinite loop.
It is entirely possible to set a value in the expression of you while loop. If you do this your expression will be evaluated which is alway true because you reset it to true everytime you do a loop.
In most programming languages, the operator = return the assigned value after calling it.
whcih means if you want to assign a variable in every iteration and the value of this variable is the condition then you will use = in the loop condition instead of ==
Example
boolean a, b;
b = true;
while(a = b){
// Some crazy things using a & b
// loop ends when b == false at the end of an iteration
}
To answer your question; It's valid because the specification says so.
You can call a method with an expression,
15.12. Method Invocation Expressions
A method invocation expression is used to invoke a class or instance method.
MethodInvocation:
MethodName ( ArgumentList opt )
ArgumentList:
Expression
ArgumentList , Expression
and an assignment is an expression,
15.26. Assignment Operators
There are 12 assignment operators; all are syntactically right-associative (they group right-to-left). Thus, a=b=c means a=(b=c), which assigns the value of c to b and then assigns the value of b to a.
AssignmentExpression:
ConditionalExpression
Assignment

Semicolon at end of 'if' statement

Today, after half an hour of searching for a bug, I discovered that it is possible to put a semicolon after an if statement instead of code, like this:
if(a == b);
// Do stuff
Which basically means that the stuff will be done whether a equals b or not, and the if statement has no point whatsoever. Why doesn't Java give me an error? Is there any situation in which this would be useful?
Why does it happen?
Java Language Specification says that:
The Empty Statement
An empty statement does nothing.
EmptyStatement:
;
Execution of an empty statement always completes normally
It essentially means that you want to execute empty statement if a==b
if(a == b);
What should you do:
There are two main solutions to this problem:
You can avoid problems with empty statement by using code formatter
and surrounding stuff inside if with { and }. By doing this
Your empty statement will be much more readable.
if(a == b){
;
}
You can also check tools used for static code analysis such as:
Findbugs
Checkstyle
Pmd
They can instantly highlight problems such as this one.
I would recommend to combine both solutions.
Is there any situation in which this would be useful?
Useful? As in "makes your code cleaner, clearer, faster, more maintainable"? Not at all. This is most likely poor, confusing code.
But it's not necessarily benign. Such a statement can perform actions and/or alter state due to methods which cause side effects, and optionally evaluate those methods due to short-circuiting of operators.
if( a() && b() );
Here, a() or b() may do something, and b() will only execute if a() is true.
As to why, I think the answer is simply that it would be worse to deviate from defined, expected behavior (e.g. statements like while(reader.read());) than the alternative of developers writing bad code.
Writing bad code is always possible. And just to reiterate, this would be bad code in almost any case.
A possible use case:
if (a==b);
else {
// Do something
}
Not good, but possible.
Still, I do think that the Java specification should disallow an empty if.
If you're using Eclipse, you can make it warn you about those statements:
If you use an if statement, the first statement after the if will be executed if the condition is true. If you have a block after the if (with curly braces), it counts for that whole block. If there is no block it counts for only one statement. A single semicolon is an empty statement. You could also write the code from you example like this:
if(a==b) {
;
}
It is an old leftover from the days when there was more syntactic sugar to differentiate expressions from statements.
Basically, the comma was used as the list item separator, so the semicolon was used as the "list of statements" separator. The downside is in the handling of null items in lists, and null statements in blocks.
In a list of items, Java uses the explicit keyword null, but a "null statement" is just an empty line. Allowing the existence of an empty line is a holdover from tradition inherited from C.
Why do it? Especially with an if statement when you know that no statements are being executed: Because some if statements have side effects:
int c;
if ((c = in.read()) != -1);
Yes, it is not the best example, but basically it says read a byte from the stream and do nothing. Might be useful in some corner cases, but even if this example isn't the best, it illustrates the intent. We want to feel the side-effects of the expression without accidentally executing any statements.
I can't think of an occasion where it is useful. It can be useful for loops like
while(do something);
or
for(init; do something; something else);
If you use your code formatting in your IDE regularly these sort of bugs become obvious. Some IDEs highlight this as a probable bug as well.
I'd agree with you there's no useful purpose to this for a human. I suspect it's there because it simplifies the language definition; it means that the thing that comes after an if is e same as the thing that comes after a while, for instance.
Why? It's because its easier for compiler writers. You don't have to make a special case to check for semicolons after if(cond) and has an added usage of allowing
if (cond && maybeFunc())
;// Code here I want to ignore
Even though it's actually a terrible idea to allow this. It's just easier to allow and then to add a case to check this.
Java allows an empty block any place a statement block is allowed. I am sure making this a general rule for all blocks simplifies the compiler.
I agree that this is primarily the cause of bugs that are spectacularly hard to find. I always use braces around blocks, even when there is a single statement, but Java allows you to make a block with braces at any point, so using braces can not save you from this fate. For example, I once wasted 4 hours trying find something like this:
while (condition);
{
statement;
statement;
}
The semicolon at the end of the first line was a typo, accidentally making the statement block for the while loop empty. Because the syntax is valid the program compiled and ran fine, just not the way I wanted it to. It was really hard to find.
I can think of one situation where it is very nice that you are allowed to have empty blocks, and this is something like this:
if (condition1) {
do_action_1();
}
else if (condition2) {
//nothing really to do in this case
}
else if (condition3) {
do_action2();
}
else {
do_action3();
}
In the above example, you want to be able to separate out various conditions. Remember, those conditions might be overlapping, so it is not always possible to rearrange the order. If one of the conditions really does not need anything done, then it is nice that Java allows you to have an empty block. Otherwise, the language would need some form of a "noop" method to use when you really do not want anything done.
I personally would prefer the explicit "noop" statement -- but that is not how Java is defined.
Just a FYI about the usability and what difference it makes or can make if there is a statement like that
Consider a piece of code like the following.
int a = 10;
if ((a = 50) == 50);
System.out.println("Value of a = " + a);
Clearly in this case, the if statement does change the output. So a statement like that can make a difference.
This is a situation where this could be useful or better to say have an impact on program.
if(a==b)
println("a equals b");
You can use an IF statement without {} if there is only a single line to be executed, so by using if(a==b); you are saying if they equal, execute and empty statement... So it will do nothing, and then return to your normal loop, outside of the IF block.
A few definitions from the jls explain this (chapter 14):
Blocks are Statements
As stated here, a Block is a StatementWithoutTrailingSubstatement, which in turn is a StatementNoShortIf, which is a Statement. Thus where ever any of these is required, we can insert a Block.
The if-clause
Though this is as well the case for for and while-loops, I'll use if-statements. These rules are pretty much the same. The syntactical description of if-statements can be found here.
IfThenStatement:
if ( Expression ) Statement
IfThenElseStatement:
if ( Expression ) StatementNoShortIf else Statement
IfThenElseStatementNoShortIf:
if ( Expression ) StatementNoShortIf else StatementNoShortIf
So we can use our block here.
But why does it work with ; ?
; is defined as the EmptyStatement (link), which is as well a StatementNoShortIf. So in conditional pieces of code, like if-statement and loops, we can replace a Block with a EmptyStatement, if a StatementNoShortIf or Statement is required.
Thus if(Expression)EmptyStatement works.
Why doesn't this give an error?
Pretty simple: java gives an error if it finds invalid syntax. But if(Expression)EmptyStatement is perfectly valid syntax. Instead javac gives a warning if launched with the proper parameters. The full list of warnings that can be dis-/enabled lists the warning-name empty for this purpose. So compilation with -Xlint:all or -Xlint:empty will generate a warning about this.
Your IDE should have an option to enable this kind of warning as well.
For eclipse, see #nullptr's answer. In IntelliJ, you can press Ctrl + Shift + A, enter empty body into the search field and enable the warning (marked in the image)
What is this even used for?
To be honest, there's not much use in it from a minimalistic point of view. There's usually a way to get things done without a "do nothing" command. It's rather a question of personal preferences, whether you rather use
if( a() && b() );
or
if( a() ) b();
and same would apply to other cases, in which the EmptyStatement is used. An important point to consider on this topic is readability of code. There are occasions, where code becomes more readable by using the no-op. On the other hand there are cases, where code becomes quite a lot harder to comprehend with using the EmptyStatement - the above example would count to the later IMO.
I can think of a scenario where an empty statement is required (not for if condition but for while loop).
When a program just want an explicit confirmation from the user to proceed. This may be required when the work after the user confirmation depends on some other things and user want to take control of when to proceed.
System.out.println("Enter Y to proceed. Waiting...");
System.out.println("");
while(!(new Scanner(System.in).next().equalsIgnoreCase("Y")));
System.out.println("Proceeding...");
// do the work here
look this:
int a,b,c = 0;
if(a == b){
c =1;
}
System.out.print(c);//1
so, you can write like this:
if (a == b)c=1;
but,if this code is this:
int a,b,c=0;
if (a != b){
}
if (a == b ){
c =1;
}
you can write like this:
if(a != b);
if(a == b )c=1;
so,you will know if(a != b); do noting
The semi-colon in the if indicates the termination of the if condition as in java ; is treated as the end of a statement, so the statement after if gets executed.
Semicolon at the end of,
if(a==b); simply finish the statement in single line which means ignore the result of condition and continue the execution from the next line
This code is useful, on the other hand sometime introduce bug in program, for example,
case 1.
a = 5;
b = 3;
if(a == b);
prinf("a and b are equal");
case 2.
a = 5;
b = 5;
if(a == b);
prinf("a and b are equal");
would print the same output on the screen...
While working on a programming assignment for class where I am working with a N by N grid of doodads and comparing characteristics of a random doodad to those above, below, left, and right, I found a nice use of this to prevent nested statements and potential boundary exceptions. My goal was to minimize code and keep from nesting if-statements.
if (row == 0);
else (method (grid[row][col], grid[row-1][col]));
if (row == N-1);
else (method (grid[row][col], grid[row+1][col]));
if (col == 0);
else (method (grid[row][col], grid[row][col-1]));
if (col == N-1);<br>
else (method (grid[row][col], grid[row][col+1]));
where method(Doodad a, Doodad b) does some operation between a and b.
Alternatively, you could use exception handling to avoid this syntax, but it works and works well for my application.

Reason for the existence of non-short-circuit logical operators

When used with boolean operands, & and | become logical operators per Section 15.22.2 of the JLS. Unlike && and ||, however, these don't short-circuit; they always evaluate both sides. I have a silly question: Why are the less-efficient non-short-circuit logical operators (&, |) still there, when we have the more-efficient short-circuit logical operators (&&, ||)? I mean, what is the real usage of the non-short-circuit logical operators, as opposed to with the short-circuit logical operators? In other words, what is the usage of always evaluating both sides by using the non-short-circuit logical operators?
Updated answer:
Apologies, I missed the word "logical" in your question even though it is there. (I've taken the liberty of emphasizing it a bit with an edit.)
Consider the case where you want any side-effects to always occur, regardless of whether the left-hand expression evaluates true or false. E.g., contrast:
if (foo() & bar()) {
// Only call this if both operations returned true
}
with
if (foo() && bar()) {
// Only call this if both operations returned true
}
Let's assume both foo and bar have effects that we want to have happen regardless of whether foo returns true or false. In the first one above, I know that bar will always get called and have its effect. In the latter, of course, bar may or may not get called. If we didn't have the non-short-circuit version, we'd have to use temporary variables:
boolean fooResult, barResult;
fooResult = foo();
barResult = bar();
if (fooResult && barResult) {
// ...
}
You might argue (I probably would) that you should do that anyway, because it's way too easy to misread if (foo() & bar()), but there we go, a pragmatic reason for having non-short-circuit versions.
Original answer:
How would you propose & (or |) be a short-circuited operator? With && and ||, it makes sense because you're dealing with boolean conditions: They can be true or false, there are no shades of grey. But & and | deal with bits, not booleans. The result is a number. I mean, I guess & could not evaluate the right-hand side if the left-hand side were 0, and similarly | could not evaluate it if the left-hand side were all-bits-on for whatever the type was, but I don't see much point to making the one edge case of each operator significant (as compared to the 254 or more other cases).
There are instances where the components of a boolean expression involve operations that you'd want to have executed in all cases. Consider the following example of checking a password for validity:
while ( !password.isValid() & (attempts++ < MAX_ATTEMPTS) ) {
// re-prompt
}
If the second condition was not evaluated due to short-circuiting, attempts would never be incremented. Thus greater programmer flexibility is enabled.
My case (C++):
void setFields(Parameters bundle)
{
if (setIfDifferent(&field1, bundle.value1) |
setIfDifferent(&field2, bundle.value2) |
setIfDifferent(&field3, bundle.value3)) {
storeState();
}
}
setIfDifferent() sets the object's field with new value if they differ, in which case it returns true; or it returns false in case the field's and the new value are the same. So, we want to try to set all fields, and if any of them changed, then we want to store new object's state.
You can have some side-effects in logical expression, for example you can assign simultaneously with checking. This may work wrongly if only one part evaluated.
Can't remember good example now, but remember that I was in need of "non-short-circuit" operators sometimes.
Hmmm.... Below is WRONG example, which won't work without "non-short-circuit" OR:
if( (object1=getInstance1()).getNumber() == 1 || (object2=getInstance2()).getNumber() == 2 ) {
// do something which requires bot object1 and object2 assigned
}
In my case, I have two methods that compare two different but related objects (Object2 is an attribute of Object1) to see if there were any changes. An update needs to happen if either are updated, but both need to be evaluated so that the objects will be modified if both have been changed. Therefore, a single pipe "OR" comparison is required.
EX:
if (compare(object1, currentObject1) | comparison(object2, currentObject2)) {
updateObject1(object1);
}
Technically, & and | are not logical, they're bitwise operators that become logical operators when associated with booleans.
There are times when you'd want to include assignment expressions inside your logical expressions.
Say:
if(a = (checkForSomeCondition()) | b = checkForAnotherCondition())
{
//now do something here with a and b that has been cached
}
If I had used ||, I'd not be able to perform the above check and would have had to split the assignments into separate statements. I've never come across scenarios like this during application development, but come across it a few times while writing algorithms.
Of course, you could use unary operators on the logical expressions or pass variables by reference into a predicate, but those seem like less common cases than the above.

Categories

Resources