I am trying to decipher this code (MurmurHash) and came across the following lines:
switch (remainder) {
case 3: k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
case 2: k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
case 1: k1 ^= (key.charCodeAt(i) & 0xff);
// When is this executed?
k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
}
My question is as follows: I have never seen code inside a switch statement that is not part of either a case or a default and would greatly appreciate it if someone could explain when the part after the last case statement is supposed to get executed.
Is it an alternative way of writing a default statement?
Or will this always get executed, just as if it were written outside of the switch block?
Information on this topic seems very difficult to come by as documentation on switch statements generally deals with case and default, and it’s also impossible to test without changing the code too much which might affect its behavior.
Thanks in advance!
>Solution :
The code is part of case 1.
Personally I’d re-arrange the whitespace to be more clear:
switch (remainder) {
case 3:
k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
case 2:
k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
case 1:
k1 ^= (key.charCodeAt(i) & 0xff);
k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
}
The point is that, without a break; in any of the cases, any matched case will execute and then control will flow to the next case.
So, assuming remainder can only be 1, 2, or 3…
- If it’s
3, all statements are executed. - If it’s
2,case 3is skipped but the rest is executed. - If it’s
1,case 3andcase 2are skipped but the rest is executed.
The logic is, perhaps a bit unintuitively, relying on the control flow of switch to continue on to the next (not-actually-matching) case.