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; } } }
The behavior in this case might be entirely compiler-specific, if nothing is stated in the standard.
However, apart from intentionally obfuscating the code, I cannot think of any case where applying a construct like this might be worthwhile.
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
What do you mean by "working"?
"K&R say nothing about 'case' into 'if'..."
Well, they couldn't possibly consider every permutation and combination of the language elements, could they... ;-)
You'd need to think about the scope of case labels...
You'd also need to comment this code very carefully so that you and other readers in the future know exactly what you intended by it...
Or you could just re-write it in a more conventional manner so that there's no doubt...
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.
If you're not sure what something should do, how can you be sure that what it does actually (appear to) do constitutes "working"...?
Christoph,
The only time I've ever seen something similar is in a method called "Duff's Device" which is a truly bizarre way of creating an unrolled loop.
en.wikipedia.org/.../Duff's_device
-Jay Daniel
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.