Why is if(true && false);{ foo(); } valid?
This is one nasty bug that took me half an hour to resolve. The compiler believes this is valid code and when it evaluates the statement, it will still call foo():
if(true && false);{ foo(); }
Why is it vali开发者_JAVA技巧d and why does foo() still get called?
Well, you didn't ask a question, but I feel obliged to tell you why the compiler is right and the code is valid (sorry, folks of SO):
if (true && false);
Is just an empty statement that executes if the condition is met (in which case it's not being met because of the && false
, so nothing happens (but either way nothing will happen)). The statement is empty because the closing parenthesis is immediately followed by the semicolon.
{ foo(); }
Is a method call enclosed in a scope block. The semicolon terminates the if condition, so this block is not relevant to the if condition at all. It's just a block, by itself. The code is executed regardless of the if condition.
It is valid code. It is an if with an empty statement, and a scope block.
In fact my compiler gives a warning for the if: Possible mistaken empty statement
If you had written:
if (true && false) { foo(); }
it would have the effect you expect.
But, if the real question is why it took you so long to find the problem, then I can tell you the problem is that you are not reading the warnings the compiler generates.
This is valid code and not a bug. Note the additional ;
you have between the if and the braces.
What your code amounts to is
if (true && false);
//...
{ foo(); }
remove the semicolon between ) and {
if (true && false) {
foo();
}
I think this is what you want.
If you just do
if(true && false);
it will stop your if-statement at the ; so all the code underneath:
foo();
is executed.
if(true && false);
;( semicolon) breaks the if loop and goes to foo();
try
if(true && false)
{ foo(); }
You can claim that the specification is stupid, but you can't claim that it's a bug in the compiler. I would have made it illegal to put a ;
directly behing an if, since I see no case where that's useful.
And since you even get a compiler warning this shouldn't be that big a problem in practice.
The correct answer has already been given, and this is not an additional answer, but it's worth pointing out anyway: Use jslint and you could have avoided this problem.
For example, here's a Javascript buffer in emacs, with flymake-for-javascript - emacs' on-the-fly syntax checker - enabled:
(ps: that image also uses flymake-cursor.el, to automatically display the error message down below)
JSLint can be run from the command line, can be included in an automated build process, or it can be integrated into a development tool. If you haven't checked it out, do so. You'll learn some good habits for Javascript coding.
精彩评论