Break for last case in switch

A

Archos

Is ok don't add a "break" statement in the last "case" one? Because
JavaScript Lint shows:

lint warning: missing break statement for last case in switch

// ===
var x = tag
switch (1) {
case x < 0:
str = "negative"; break;
default:
str = "positive";
}
// ===
 
J

Jukka K. Korpela

A 'break;' at the end of the last clause in
a switch statement would be redundant.

Indeed, but some redundant constructs may be regarded as recommendable
by some.

I'd say file a bug, but the
warning might even be intentional.

It looks like intentional, as it seems to have a message of its own
"missing break statement for last case in switch" instead of the general
warning "missing break statement"
Lint tools sometimes have odd notions
about what is and isn't "good style".

I think that's part of the game. :)

The only reason for such warnings that I can figure out is protection
against changes. If new cases are appended into the content of the
switch statement (or the cases are reordered), then it's somewhat safer
that you don't need to add a break statement before it.
 
A

Antony Scriven

JavaScript Lint is mistaken. A 'break;' at the end of the
last clause in a switch statement would be redundant. I'd
say file a bug, but the warning might even be
intentional. Lint tools sometimes have odd notions about
what is and isn't "good style".

Well you have to ask yourself the following questions.
What's the cost of adding the `break'? What's the cost of
leaving it out?
At least JavaScript Lint offers a way to exclude parts of
the code from checking.

Yes, it's very customisable if you disagree with its
decisions. --Antony
 
T

Thomas 'PointedEars' Lahn

Stefan said:
JavaScript Lint is mistaken.

You are mistaken.
A 'break;' at the end of the last clause in a switch statement would be
redundant.

var x = 0,
y = -1;

switch (1)
{
case x < 1:
y = x;
break;

default:
/* 0 */
console.log(x);
y = 42;

case 2:
y = 23;
}

/* 23 */
console.log(y);

It should be added that this result makes it rather obvious that, on top of
the facts that omitting the `break' statement is error-prone considering
code extensions, and that this approach is poor code style indeed (use the
`if' statement instead), the approach simply does not work.

`x < 0' evaluates to a Boolean primitive value (either `true' or `false'),
never to the Number primitive value `1' (type conversion is _not_
performed); therefore, the `default' clause will be considered. If the
`default' clause does not contain a `break' statement as last in its
/StatementList/, subsequent `case' clauses will be considered *without*
checking. This is conforming with ECMA-262 Ed. 5.1, section 12.11 ("The
switch Statement").


PointedEars
 
T

Thomas 'PointedEars' Lahn

Stefan said:
No. Please re-read what I wrote. I said:

Please re-read what you have replied to in the first place.
I did _not_ say "at the end of the default clause".

The "last case" in the original code is the `default' clause. ISTM *that*
was here the missing `break' statement was being warned about. Rather
ambiguously for sure, but there it was.
And as expected, nothing changes when you add "break" after "y = 23".

What changes then is that there is no fall-through in either case. The
fall-through for the `default' clause is rather unintuitive: Subsequent
`case' clauses will be fallen through if neither the first "block" of `case'
clauses nor the second one found a match. IOW, the code above will be
processed as if it was

var x = 0,
y = -1;

switch (1)
{
case x < 1:
y = x;
break;

case 2:
y = 23;

default:
/* 0 */
console.log(x);
y = 42;

y = 23;
}

/* 23 */
console.log(y);

Did you *really* expect that? And that is still not the complete truth, see
step 9 in the aforementioned section. There is actually a good reason for
step 8c ("abrupt completion", e. g. by `break' statement) even in a
`default' clause's /StatementList/.
[...] omitting the `break' statement is error-prone considering
code extensions [...]

I assume that was the cause for the warning in JavaScript Lint. This is
a typical case of "my code conventions are superior to yours."

No, it appears to be a case of "this is potentially error-prone, avoid it".
After all, it is a *warning*, not an error. A warning that is justified,
given the Specification for the `switch' statement.
I prefer tools which let me configure which warnings I want to see,
instead of annoying me with the author's pet peeves. JSL is much, much
better in this regard than JSLint.

Apparently not good enough for you.
Talking about code conventions... do you think it's a good idea to put
'default' clauses above 'case' clauses in switch statements?

Mu. It is syntactically valid and may conveniently do what you expected it
to (as specified) in some cases.


PointedEars
 
J

Jukka K. Korpela

2011-12-18 23:29 said:
Please re-read what you have replied to in the first place.

The question about about break for last case in switch, as one can see
even in the Subject line. You misread it and gave a typical verbose
lecture on something else; now you're accusing someone else of misreading.
The "last case" in the original code is the `default' clause.

It had to have some code, and it happened to be the default clause, but
the question was clearly about last case.
ISTM *that*
was here the missing `break' statement was being warned about. Rather
ambiguously for sure, but there it was.

There is no ambiguity here. If you actually checked what JavaScript Lint
says about

switch (1) {
default:
str = "positive";
break;
case x < 0:
str = "negative";

}

you would see that it warns "missing break statement for last case in
switch" here, too.
The fall-through for the `default' clause is rather unintuitive:

No more than fall-through from a case to another in general. And
everyone who has a chance of understanding the original question surely
knows the fall-through principle (it was implied in the question) and
its dangers. The question was about a specific detail in it.
 
T

Thomas 'PointedEars' Lahn

Thomas said:
Please re-read what you have replied to in the first place.


The "last case" in the original code is the `default' clause. ISTM *that*
was here the missing `break' statement was being warned about. Rather
ambiguously for sure, but there it was.

And regardless of the misconceptions of a well-known wannabe, that is
exactly what happened here.

<http://www.javascriptlint.com/online_lint.php> shows *two* warnings for
this code –

Line 3, column 1: "lint warning: missing semicolon"
Line 8, column 1: "lint warning: missing break statement for last case in
switch"

– while, if the `break' statement in the last `case' clause is omitted, it
shows *three* warnings:

Line 3, column 1: "lint warning: missing semicolon"
Line 6, column 9: "lint warning: missing break statement"
Line 8, column 1: "lint warning: missing break statement for last case in
switch"

So it is not a bug, it is a feature. A questionable feature because it uses
ambiguous wording, but there it is.


PointedEars
 
J

Jukka K. Korpela

2011-12-19 0:09 said:
– while, if the `break' statement in the last `case' clause is omitted, it
shows *three* warnings:

Line 3, column 1: "lint warning: missing semicolon"
Line 6, column 9: "lint warning: missing break statement"
Line 8, column 1: "lint warning: missing break statement for last case in
switch"

So, once again, this disproves your claim that the error message
“missing break statement for last case in switch†does not relate to
missing break statement for last case in switch but to “default†case.

If this is not clear enough, you could try JavaScript Lint on a switch
statement that contains no “default†case.
 
T

Thomas 'PointedEars' Lahn

Stefan said:
Of course. I don't know why you keep going on about that. There were no
other clauses without breaks. That's why I specifically said "the last
clause", including both "case" and "default".

"case" obviously does not mean for JavaScriptLint what it means for you, and
there can only be *one* last clause. In either case, you are wrong.
Or in other words... nothing changes :)
Whatever you do, a 'break' at that position cannot possibly change the
outcome. It is, as I said, redundant.

No, look closer. It does not change the outcome *here* because `2' cannot
possibly be a match for the value to be found by the algorithm.
First you ask me if I really expected how your switch worked (implying
that something unusual or complicated was going on),

It is.
and now you defend it?

No. I have merely answered your question in a way that you had not expected
(or comprehended yet).
I contend that such constructs are far worse than leaving out the
final 'break', especially if the last clause is 'default'.

There is no inherent programming problem with it if you put the `break'
statement where needed, for then the `switch' statement is semantically
identical. Of course, leaving the `default' clause in-between would cause
*maintenance* problems at little advantage *then*, and that would probably
qualify for a bad idea.

There is no inherent problem with it if the specified behavior when omitting
the `break' is what is *intended* (like a `finally' clause in `try-catch'
statements). Iff that is causing a maintenance problem, then different
approaches need to be considered. But it is not a bad idea in itself, and
so does not qualify as not being a good idea either.

So yours is not a question that can be answered correctly with a simple
"Yes" or "No"; it is a question that reveals your ignorance about the
subject discussed. Which is why I replied "Mu".
If you find program flow like that "convenient", I have a Duff's device
to sell you :)

Straw man.
 
T

Thomas 'PointedEars' Lahn

Stefan said:
Alright, then give us a counter example.

switch (1) {
/*
* your code here
*/
break; // <-- this will make a difference, according to you
}

You are still missing the point.

A)

var x = 2;
var outcome = -1;

switch (x)
{
case 1:
console.log("case 1");

default:
console.log("default");
outcome = "default";

case 2:
console.log("case 2");
outcome = 2;
}

console.log(outcome);

Console output:

| case 2
| 2


B)

var x = 3;
var outcome = -1;

switch (x)
{
case 1:
console.log("case 1");

default:
console.log("case default");
outcome = "default";

case 2:
console.log("case 2");
outcome = 2;
}

console.log(outcome);

Console output:

| case default
| case 2
| 2


C)

var x = 3;
var outcome = -1;

switch (x)
{
case 1:
console.log("case 1");

default:
console.log("case default");
outcome = "default";
break;

case 2:
console.log("case 2");
outcome = 2;
}

console.log(outcome);

Console output:

| case default
| default

A similar, more well-known fall-through occurs if the previously last `case'
clause of a `switch' statement is not the last `case' clause anymore.

It makes sense for a lint for ECMAScript implementations to issue a warning
if the `break' statement is missing for the last clause (in JavaScriptLint
terminology: "the last case") of a `switch' statement (_not_ necessarily
meaning "last `case' *clause*") in order to avoid accidental fall-through in
the future. From the results (*three* warnings) I am getting when omitting
the other `break' statement as well, it is obvious to me that this was the
*intention* of the JavaScriptLint authors, so it cannot be considered a bug.
(A bug worth reporting is the ambiguous wording in the warning; they should
have used "clause", not "case".)


PointedEars
 
J

Jukka K. Korpela

On 2011-12-19 00:06, Thomas 'PointedEars' Lahn wrote: [...]
Alright, then give us a counter example.

It’s time to move on; the troll has decided to stick to his
misrepresentation of facts and to continue with all kinds of topics that
do not address the issue at hand.

The original question has been settled down, despite the troll’s
attempts at confusing everyone.

JavaScript Lint issues warnings about missing “break†statements in
cases of a “switch†statement. The normal message “missing break
statement†should be taken seriously, since in most cases, it reveals a
real error: you really didn’t want to fall through. The special message
“missing break statement for last case in switch†is a potentially
useful warning, too, but at a different level—it relates to the
robustness of code considering possible future changes.
 
J

John G Harris

On 2011-12-19 00:06, Thomas 'PointedEars' Lahn wrote: [...]
Alright, then give us a counter example.

It’s time to move on; the troll has decided to stick to his
misrepresentation of facts and to continue with all kinds of topics
that do not address the issue at hand.

The original question has been settled down, despite the troll’s
attempts at confusing everyone.

JavaScript Lint issues warnings about missing “break†statements in
cases of a “switch†statement. The normal message “missing break
statement†should be taken seriously, since in most cases, it reveals
a real error: you really didn’t want to fall through. The special
message “missing break statement for last case in switch†is a
potentially useful warning, too, but at a different level—it relates
to the robustness of code considering possible future changes.

Also lint should complain if 'default' isn't at the end. Semantically it
belongs at the end and might be overlooked when the switch statement is
being updated/maintained.

John
 
J

Jukka K. Korpela

2011-12-19 17:50 said:
Also lint should complain if 'default' isn't at the end.

JavaScript Lint does. It warns “the default case is not at the end of
the switch statement†if a default case is present but not the last one,
and “missing default case in switch statement†if there is no default
case at all.

These are independent of the warning “missing break statement for last
case in switch.â€
 
E

Evertjan.

Thomas 'PointedEars' Lahn wrote on 19 dec 2011 in comp.lang.javascript:
It makes sense for a lint for ECMAScript implementations to issue a
warning if the `break' statement is missing for the last clause (in
JavaScriptLint

No it does not make sense.

Despite the name 'switch' suggesting otherwise,
the facultativity of the brack and default statements
make the statement very versatile:

var c=9, a=0, myCondition=true, count=0;

switch(true) {
default :
alert('default on top');
case (c>5):
count++;
case (a>-7):
count++;
case (myCondition):
count++;
case (f===undefined):
count++;
};

alert('Number of conditions satisfied: ' + count); // 4

=========================

btw:
The 'default on top' alert does not even fire both in Chrome ansd IE9,
I would have liked to park "var count-0;" there.

btw2:
Versatile or not,
I see no need for the switch() statement for myself,
I prefer the more logical if-else and complex boolean expressions.
 
G

Gene Wirchenko

Thomas 'PointedEars' Lahn wrote on 19 dec 2011 in comp.lang.javascript:
No it does not make sense.

It does if you are thinking of code maintenance. Some think that
it is too easy to add a case to the end and forget the break.
Personally, I avoid C-style cases because of the stupidity of
requiring break.
Despite the name 'switch' suggesting otherwise,
the facultativity of the brack and default statements
make the statement very versatile:
^^^^^^^^^
This can also be read as "often used to write obfuscated code
(whether deliberately or not)".
var c=9, a=0, myCondition=true, count=0;

switch(true) {
default :
alert('default on top');
case (c>5):
count++;
case (a>-7):
count++;
case (myCondition):
count++;
case (f===undefined):
count++;
};

alert('Number of conditions satisfied: ' + count); // 4

=========================

btw:
The 'default on top' alert does not even fire both in Chrome ansd IE9,
I would have liked to park "var count-0;" there.

Why should it? Since the case (c>5) applies, default does not.
btw2:
Versatile or not,
I see no need for the switch() statement for myself,
I prefer the more logical if-else and complex boolean expressions.

As do I.

Sincerely,

Gene Wirchenko
 
G

Gene Wirchenko

On Mon, 19 Dec 2011 15:50:36 +0000, John G Harris

[snip]
Also lint should complain if 'default' isn't at the end. Semantically it
belongs at the end and might be overlooked when the switch statement is
being updated/maintained.

"Semantically"? Why?

If you think of it as a final alternative, but I can see someone
having the situation of:
Do this action (the default) except when one of the following
special cases applies in which case, do the first special case that
applies.

If the special cases are rare, why not have the usual case (the
default) first?

Sincerely,

Gene Wirchenko
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top