How to Get Fired Using Switch Statements and Statement Expressions (2016)

downbad_1 pts0 comments

How to Get Fired Using Switch Statements & Statement Expressions

Home

Store

Blog

Contact

Home

Store

Blog

Contact

#linux

#commandline

#softwareengineering

#embeddedsystems

#compilers

...

View All >>

How to Get Fired Using Switch Statements & Statement Expressions

2016-10-27 - By Robert Elder

Updated Oct 27, 2016: Fixed sample code comments in coroutine example as per suggestion, edited text to note D's similar behaviour.

Updated Oct 28, 2016: Added missing colon., corrected Duff's device example.

Introduction

It doesn't matter whether you're trying to achieve job security; impressing others by showing them how smart you are; or passive aggressively asserting your dominance over a code base, writing unmaintainable code has a number of practical applications. One extremely unmaintainable and bug-ridden technique for C programming involves using both switch statements and statement expressions together.

In this article, we will discuss how you can leverage switch statements and statement expressions to produce C code that is so difficult to understand, you'll need to look at the assembly to figure out what it does. Many of the examples of syntax in this article are not standards compliant or they won't pass even the simplest of static analysis tests. That should be ok though, because writing many of these examples in your company's code base will probably end up getting you fired anyway.

Switch Statements

Let's start by reviewing the humble switch statement that we all know and love:

int i = ...;<br>switch(i){<br>case 0:{<br>...<br>break;<br>}case 1:{<br>...<br>break;<br>}case 2:{<br>...<br>break;<br>}default:{<br>...

The above is what most people are used to thinking about when 'switch statements' are mentioned in C. The rough idea is that switch statements are a sort of more appealing alternative to using lots of 'else if' statements when checking for some disjoint property. Some of you may be surprised to learn that the following is also a valid switch statement:

int i = ...;<br>switch(i){<br>i++;<br>default:{ }<br>i++;<br>case 0:{<br>case 3: i;<br>if(i 10){<br>case 1:{<br>break;<br>for(i=0; i 10; i++){<br>case 2:;

It's worth pointing out that almost no other languages support switch statements the way that they work in C (although the D language is an example). Most other languages have a switch statement that works similar to the idea of a more appealing alternative to many 'else if' checks.

How Do Switch Statements In C Actually Work?

A switch statement in C would be more appropriately called a 'goto field'. This means that the switch(...) part simply makes a decision about which label to branch to. After branching to that label nothing special happens related to the fact that you're inside a switch statement and the code will just keep executing whatever machine instructions come next. The one exception is, of course, the break statement which will jump to the point after the switch statement body. Here is an equivalent version of the switch statement written above using only ifs and gotos.

int i = ...;<br>if(i == 0)<br>goto label_0;<br>if(i == 1)<br>goto label_1;<br>if(i == 2)<br>goto label_2;<br>if(i == 3)<br>goto label_3;<br>/* Otherwise, go to default label */<br>goto label_default;

i++;<br>label_default:{ }<br>i++;<br>label_0:{<br>label_3: i;<br>if(i 10){<br>label_1:{<br>goto break_from_switch;<br>for(i=0; i 10; i++){<br>label_2:;<br>break_from_switch:

If you're already familiar with the famous Duff's device the above this probably isn't news to you:

/* The switch statement used in Duff's device */<br>int total_bytes = ...;<br>int n = (total_bytes + 3) / 4;<br>switch (total_bytes % 4) {<br>case 0: do { *to = *from++;<br>case 3: *to = *from++;<br>case 2: *to = *from++;<br>case 1: *to = *from++;<br>} while (--n > 0);

Co-Routines Using Switch Statements

Drawing on Duff's device as inspiration you can use the unique behaviour of switch statements in C to implement coroutines:

#include

#define coroutine_begin() static int state=0; switch(state) { case 0:<br>#define coroutine_return(x) { state=__LINE__; return x; case __LINE__:; }<br>#define coroutine_finish() }

int get_next(void) {<br>static int i = 0;<br>coroutine_begin();<br>while (1){<br>coroutine_return(++i);<br>coroutine_return(100);<br>coroutine_finish();

int main(void){<br>printf("i is %d\n", get_next()); /* Prints 'i is 1' */<br>printf("i is %d\n", get_next()); /* Prints 'i is 100' */<br>printf("i is %d\n", get_next()); /* Prints 'i is 2' */<br>printf("i is %d\n", get_next()); /* Prints 'i is 100' */<br>return 0;

The example in this section draws on one found in Coroutines in C by Simon Tatham. The original source describes a few caveats of switch based coroutines that I won't discuss in this article.

If we resolve the macros, and indent the code a bit better, then remove some superfluous brackets and semicolons, the 'get_next' function becomes:

#include

/* Assume the value of __LINE__ was 1234, and 4567 */

int get_next(void) {<br>static int i = 0;<br>static int state = 0;<br>switch(state) {<br>case 0:;<br>while(1){<br>state = 1234;<br>return ++i;<br>case 1234:;<br>state = 4567;<br>return 100;<br>case 4567:;

The static...

switch case statement statements using code

Related Articles