Hello, I was working on a ARM project with my Keil toolchain, and by chance I just found that the following code is working (see case 2); I tested it in the ARM simulator using different values for alfa and beta. Someone knows where can I find more detailed explanation about this behaviour of C language (K&R say nothing about "case" into "if"...)? Thanks in advance. Bruno
char alfa; char beta; char zeta; int main (void) { while (1) { switch (alfa) { case 0: zeta = 17; break; case 1: zeta = 91; break; case 2: if (beta == 1) { case 3: zeta = 38; break; case 4: zeta = 47; } break; } } }
I only have H&S and the standard handy at the moment. The code is valid, is dealt with in H&S, and isn't disallowed by the standard. 'switch' is essentially a computed 'goto', so why shouldn't it work? Whether it's good form or not is another question.
Well, in fact I found that "strange" code form in a bigger program (written by a customer, not written by me) and I reduced it in the small example I published. When I say "it's working" I mean it compiles, links and executes as expected; I would never guess something like this would just compile, but it does... I agree with you, it is unreadable: I will never use it in my code, but it could be a starting point for the IOCCC (International Obfuscated C Code Contest) :-))). Many thanks to all of you for your replies. Bruno
If you're not sure what something should do, how can you be sure that what it does actually (appear to) do constitutes "working"...?
Note that if you look at switch as a computed goto, the code will logically perform this:
switch (alfa) { case 0: zeta = 17; break; case 1: zeta = 91; break; case 2: if (beta != 1) break; case 3: zeta = 38; break; case 4: zeta = 47; }
In other worlds, case 2 will have a conditional break.
The main difference will however be the extra block scope in the original post, for example affecting lifetime of auto variables.
Shouldn't that be
switch (alfa) { case 0: zeta = 17; break; case 1: zeta = 91; break; case 2: if (beta == 1) zeta = 38; break; case 3: zeta = 38; break; case 4: zeta = 47; }
No, I intentionally reversed the condition, to make the code conditionally fall through to the next case value, just as the OP code does.
For production code that lets a case value fall through to the next, a comment should always be added to make sure other readers knows that the break wasn't forgotten.