Why do the following raise an error?
for(; 0 ;) System.out.println("guess"); // or
for(;false;) System.out.println("guess"); // or
for(; 1 ;) System.out.println("guess");
But the following runs okay (infinitely):
for(;true;) System.out.println("guess");
Why does it work for true but not for false?
The condition (i.e. the bit between the ;s) must be a boolean, so this immediately rules out the first and third variants in your first snippet.
Now, the second variant, in which you have used a boolean, doesn't compile because the compiler realizes that the loop will never be entered and hence issues an error:
Untitled.java:3: error: unreachable statement
for(;false;) System.out.println("guess");
^
1 error
Note that the JLS mandates that errors be issued for unreachable statements (see §14.21):
It is a compile-time error if a statement cannot be executed because it is unreachable.
...
The contained statement is reachable iff the for statement is reachable and the condition expression is not a constant expression whose value is false.
Java requires a boolean as second parameter in your loop header, it evaluates the statement and if the statement returns true the jvm will run the code of the loop-body, not the body will be skipped.
0 and 1 are obviously no booleans nor do they define a statement which could be evaluated (like x < y) and since java is a static and strong typed language (unlike Python or Perl) it cannot cast an int to a boolean, so it crashes.
Edit: If you provide "false" as statement the JVM will notice that the loop-body never can be reached, this will cause a runtime-error.
Unlike C, in Java, true and false correspond to boolean type values, where 1 and 0 to int (in fact, in C there is no boolean declarative type, and boolean checks are done based on integer comparisons. In Java, things are distinct).
Related
I have a program I need to implement that has the following code:
for (int n = 1024; true; n+=n)
I cannot find any other examples of java loops having such a format. What does this mean? I've tried to research it, but I don't even know what to search for - it's totally foreign to me.
The basic for statement is described in the language spec:
for ( [ForInit] ; [Expression] ; [ForUpdate] ) Statement
You are asking about the case when Expression is true. (The square brackets above mean it is optional).
The meaning of that is described just below, in Sec 14.14.1.2:
If the Expression is not present, or it is present and the value resulting from its evaluation (including any possible unboxing) is true, then the contained Statement is executed.
...
If the Expression is present and the value resulting from its evaluation (including any possible unboxing) is false, no further action is taken and the forstatement completes normally.
So, Expression is present, and evaluates to true (because true evaluates to true). Hence, Statement is executed, and will continue to be executed because Expression remains true.
As such, it is an infinite loop (unless there is a break, return, throw or System.exit inside the loop).
Why you dont use another loop? Use for example do-while instead of
for (int n = 1024; true; n+=n)
You can make a work around with:
int n=1024;
do{
//your code
n+=n;
}while(condition==false);
I apologize if this question has been asked somewhere in Empty for loop - for(;;) or else where on the site.
I was wondering if any one knows why java would choose for their parser/compiler to evaluate an empty conditional statement in a for(;;){} loop as true instead of perhaps null or void ?
as linked by user #Mchi
https://developer.mozilla.org/en/JavaScript/Reference/Statements/for
"An expression to be evaluated before each loop iteration. If this expression evaluates to true, statement is executed. This conditional test is optional. If omitted, the condition always evaluates to true. If the expression evaluates to false, execution skips to the first expression following the for construct."
I am just curious.
A conditional statement must be of boolean type in order to control looping, in exactly the same way that the expression within an if() or a while() statement must be of boolean type.
The only valid values for boolean are true and false. So, null and void are not applicable, they do not make any sense.
As for empty conditional statements, of the two possible values true and false, they chose true because there is absolutely never any need for a loop that will not loop at all, while there are plenty of situations where we have a need for a loop that will loop forever (or until break.)
I tried the below code in both java and c++ , but it throwed an error in java while it does not throw an error in c++. Why is it so ?
while("abc"){ }
I do know it purely depends on the property of languages. But I would like to know why java set a condition that only boolean values should be allowed in loops ?
I believe you are talking about compiler error and not run-time
in case of java
while ( expression ) {
// expression must evaluate to boolean value true or false
// as far as I knwo "abc" is neither true or false when it comes to java hence error
}
in C
while ( expression ) {
// expression can be anything which finally gives a value of either 0 or a number
// "abc" in this case will evaluate to an address which is positive integer hence no error
}
It is because of the same reason that while(1) is allowed in C but not in Java. Both of the languages evaluate expressions differently.
In case of C, there was originally no boolean type (it was introduced in C99), and any integer that is 0 was decided to be 'false', otherwise to be considered 'true'. In expression:
while("abc")
It resolves to the address which is positive integer so it works.
In case of Java, expressions must evaluate to true or false value. String "abc" does not evaluate to a boolean value so an error is observed.
Because in java The while statement evaluates expression, which must return a boolean value.You can read about it here: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html
C allows you to type anything you want in a condition of while loop.
If you dissasemble C while( something ), you will see, that the value in the parentheses is loaded in the eax register (in your case, value in the parentheses is the address of "abc"), then eax checks for zero and, if it is zero, loop ends. Like this:
mov eax, <"abc" offset>
test eax, eax
je <"after loop" offset>
jmp <loop offset>
P.S.:Because "abc" offset is a non-zero value, your loop will never end.
Note that C is the oddball in this case, not Java. Most of C's contemporaries (Fortran, Pascal, old-school BASIC, etc.) behave like Java, where the condition must be a Boolean value (or a Boolean-valued expression). C didn't acquire a true Boolean datatype until the 1999 revision, long after a whole generation of C programmers (myself included) grew accustomed to writing code without it.
In C, any non-zero integral value is considered true in a Boolean context. It's a common idiom to check that a pointer value isn't NULL as follows:
FILE *in = fopen( filename, "r" );
if ( in )
{
// in is not NULL, fopen was successful
}
As long as the pointer value in is not NULL, the condition evaluates to true. The risk with this approach is that non-NULL pointer values aren't necessarily valid pointer values. It will be in this case (fopen will return either a valid pointer value or NULL), but code like the following:
void foo ( void )
{
int *p;
...
if ( p ) { ... }
...
}
is risky; if p is never initialized or assigned to, then it will contain an indeterminate value which will most likely be neither a valid pointer nor NULL.
In most other languages, the same condition would be written as the equivalent of
if ( in != NULL )
which is a Boolean-valued expression that can only yield the values true and false.
Since "abc" evaluates to a non-zero pointer value, it can be used in a similar context (although it's not very useful, since the address will never change).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Does Java evaluate remaining conditions after boolean result is known?
When executing code with multiple && statements in java, does the compiler continue to resolve additional boolean comparisons if the first one resolves to false?
if (1==2 && 3==4 && 4==5) { Do Something }
Once determining 1==2 is false, will the compiler immediately break out of the if statement or will it continue to resolve 3==4 and 4==5 after?
In the case of && it'll stop evaluating the moment it detects that one of the conditions is false. This is called short circuit evaluation.
"SHORT CIRCUIT EVALUATION IN PROGRAMMING LANGUAGES"
In the case of any logical expression most compiler stop evaluation expression as soon as result evaluated. its not only in Java but in almost in every language. (but not all e.g. VB6)
You can also check it as follows:
i = 0 , j =1;
i && ++j;
system.out.print(" j=" + j);
The value of j will be 1, it means ++j was not executed.
does the compiler continue to resolve additional boolean comparisons if the first one resolves to false
The short answer. No! The compiler javac and the JIT analyses statically all the code. It doesn't take short cuts like this. e.g. if the second condition doesn't compile, you will always get a compilation error regardless of the first condition.
What you may have intended to ask is; will the program execute the other conditions if the first or second one is false In this case, it will not.
This doesn't make a difference for the compiler -- all it does is resolve the boolean comparisons into machine code, represented by one or more .class files.
As far as the actual runtime... If I remember correctly from Computer Science class, both Tarun's and Lews's answers are correct -- the comparison will short-circuit as soon as it gets to an expression that isn't true.
IF "1==2" is false than the compiler will immediately break out the if statement.
&&
- The above is a short-circuit AND operator. If the 1st condition results in false the 2nd condition is not evaluated.
Eg:
if ((a==false) && (b==true)){
}
The above will stop after the first evaluation.
- If you want to force the evaluation of both the conditions, then try Non-Short Circuit AND (&)
A sidenote to the keyword 'Efficiency' in your title :- as stated by other answers your basic question is easily answered, so it's not a question of efficiency, but a question if you need for some reason all expressions to be evaluated, for example when executing code which changes state (which would be by the way not good coding at all).
But if you think of 'Efficiency' in terms of executing speed, then you almost never have to optimize on that level, either the compiler will do it for you or you wouldn't notice the difference. It may be important in some time critical operation or in operations which run in very big loops, but in nearly every other case, it's much more important to write clean code, so that another human can read it well.
i saw somewhere in GWT code , it was something like this
assert display instanceof Widget : "display must extend Widget";
The assert keyword, as the name implies, makes an assertion about the code. It is used to specify something that holds true all the time -- or that, at least, should be true!
The assert keyword is followed by a boolean value (true or false), or an expression, to be evaluated at runtime, that returns a boolean.
assert true;
assert 1 == 1;
If, for any reason, the boolean expression evaluates to false, then an AssertionError is thrown.
// this will throw an AssertionError:
int x = 1;
assert x == 2;
When you use it, you make a clear statement about the state of your program on a given point, which can make it easier for readers to follow through your code.
There's a programming paradigm called program by contract, in which pieces of code make statements about the pre-conditions that must hold true for them to execute properly, and the post-conditions, that are guaranteed to hold true after their execution. You can use the assert keyword to implement this.
For example, if you write a method that calculates the square root of a number, it will only work for numbers that are greater than or equal to zero, and the result is guaranteed to satisfy the same conditions:
public double sqrt(final double x) {
assert x >= 0 : "Cannot calculate the square root of a negative number!"
double result = ...;
assert result >= 0 : "Something went wrong when calculating the square root!"
return result;
}
The most interesting aspect of assertions is that you can ask the compiler to remove them from the bytecode (by means of the -disableassertion argument), so that you won't get any kind of performance penalty at runtime on production. For this precise reason, it is of fundamental importance that the expression to be evaluate does not cause side-effects, that is, the expression should look like a pure mathematical function. Otherwise, the behavior of your program could change if the compiler removed your assertions.
Finally, if the assertions are compiled into the bytecode, they can be read by a software that will automatically generate tests that will try to break your code. It can be useful to find bugs earlier!
The assert keyword was introduced in 1.4 (follow that link for a complete description). It is a shorthand to throw an exception at runtime if a condition is not satisfied.
Think of it as
assert condition : message
as
if ( ! condition ) {
throw new AssertionError ( message ) ;
}
The idea is to give developers an easy way to help users (in your case GWT API users) to detect common errors/pitfalls
When it was introduced, the assert statement became a reserved word and that caused a few compilation issues when old code was recompiled for I.4. Especially for JUnit test suites where there was a much used assert() method. JUnit reacted by replacing assert with assertTrue()
It means that if display isn't an object of type Widget, you'll get an AssertionError with the text string that follows the assertion. Assertions are helpful for debugging.
assert keyword is used to simplify the userdefined exception.what happens,to define a userdefined exception we have to create our own exception class by defining the exception causing condition first then we have to throw that in our program.
but from java 1.5 onwards we have a keyword as assert where only we have to write assert(condition) if condtion is true it executes the other part of the program or else if it is false the it creates the object of AssertionError class and we have to handle it.
so no need to define our userdefind error.
The following text (emphasis mine) explains various forms of assertions clearly:
The assertion statement has two forms.
The first, simpler form is:
assert Expression1 ;
where Expression1 is a boolean expression. When
the system runs the assertion, it evaluates Expression1 and if it is
false throws an AssertionError with no detail message.
The second form of the assertion statement is:
assert Expression1 : Expression2 ; (Your example falls here)
where: Expression1 is a boolean expression. Expression2 is an expression that
has a value. (It cannot be an invocation of a method that is declared
void.) Use this version of the assert statement to provide a detail
message for the AssertionError. The system passes the value of
Expression2 to the appropriate AssertionError constructor, which uses
the string representation of the value as the error's detail message.
Also, refer the following oracle link for detailed information:
http://docs.oracle.com/javase/7/docs/technotes/guides/language/assert.html