{"id":1140,"date":"2022-02-15T10:59:17","date_gmt":"2022-02-15T10:59:17","guid":{"rendered":"https:\/\/marketaylor.synology.me\/?p=1140"},"modified":"2022-02-25T10:03:18","modified_gmt":"2022-02-25T10:03:18","slug":"c-switch-statement-efficiency","status":"publish","type":"post","link":"https:\/\/marketaylor.synology.me\/?p=1140","title":{"rendered":"C switch statement efficiency"},"content":{"rendered":"\n<p>MQ V8 introduced a header file, <em>cmqstrc.h<\/em>, that maps constants in the MQI to string values. I&#8217;ve mentioned it a few times <a href=\"https:\/\/marketaylor.synology.me\/?p=1070\" target=\"_blank\" rel=\"noreferrer noopener\">recently<\/a>, both here and in some other forums. One question came in, asking about how well that code worked. So I&#8217;ve recreated some tests I wrote back in <a href=\"https:\/\/marketaylor.synology.me\/?p=441\" target=\"_blank\" rel=\"noreferrer noopener\">2015<\/a>, to demonstrate what compilers do with that pattern. This shows the efficiency of writing large switch statements in C.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>There&#8217;s a phrase I&#8217;ve seen a few times but whose source I can&#8217;t discover: &#8220;you have to write a compiler three times before you can call yourself a compiler writer&#8221;. I&#8217;ve never needed to write a compiler or assembler, unless you count a <a href=\"https:\/\/www.corewars.org\/\">Core Wars<\/a> implementation in FORTRAN (the course requirement language). And the last time I did anything serious with writing machine code I  was using this book (and I wasn&#8217;t <a href=\"https:\/\/www.pagetable.com\/?p=64\" target=\"_blank\" rel=\"noreferrer noopener\">programming a Terminator<\/a>):<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized is-style-default\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/2022\/02\/6502.png\" alt=\"6502 assembler\" class=\"wp-image-1143\" width=\"129\" height=\"192\" srcset=\"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/2022\/02\/6502.png 516w, https:\/\/marketaylor.synology.me\/wp-content\/uploads\/2022\/02\/6502-202x300.png 202w\" sizes=\"auto, (max-width: 129px) 85vw, 129px\" \/><figcaption>8-bit assembly<\/figcaption><\/figure>\n\n\n\n<p>But very little specialised knowledge was needed to do this investigation, and (hopefully) to explain what I found.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The switch pattern<\/h3>\n\n\n\n<p>The repeated pattern of the MQ header file is a set of switch statements, one for each &#8220;prefix&#8221; in the MQI, with each prefix given a separate function. For example, to convert MQCC values into the corresponding strings, there is<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> char *MQCC_STR (MQLONG v)\n  {\n    char *c;\n    switch (v)\n    {\n    case         -1: c = \"MQCC_UNKNOWN\"; break;\n    case          0: c = \"MQCC_OK\"; break;\n    case          1: c = \"MQCC_WARNING\"; break;\n    case          2: c = \"MQCC_FAILED\"; break;\n    default: c = \"\"; break;\n    }\n    return c;\n  }<\/pre>\n\n\n\n<p>What actually happens when you call that function? And how might it behave in a much larger function such as <code>MQRC_STR<\/code> &#8211; nearly 600 cases? Should I split the <code>MQRC_STR<\/code> function into subgroups, or reorder the statements in some way?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The test program<\/h3>\n\n\n\n<p>I wrote two pieces of code. One a trivial bit of C that calls a switch block:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#include &lt;stdio.h&gt;\nchar *switchTest(int i) {\n  switch (i) {\n  #include \"gen.txt\" \/\/ A script-generated block\n  default:\n    return \"N\/A\";\n  }\n}\nint main()  {\n  int i=2035;\n  printf(\"Returned value of %d is \\\"%s\\\"\\n\",i,switchTest(i));\n  return(0);\n}<\/pre>\n\n\n\n<p>And the other is a shell script that generated the contents of that switch:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/bash\nfunction gen {\n start=$1; stop=$2; filter=$3\n for i in $(seq $start $stop); do\n   mod=$(($RANDOM % $filter)) # Knock out a few lines\n   if [ $mod -ne 0 ]\n   then\n     echo \"case $i: return \\\"$i\\\";\"\n   fi\n done\n}\n# Filter can be made smaller to remove more random entries\ngen 2001 2003 32767 &gt; gen.txt\n<\/pre>\n\n\n\n<p>So we have this file as the main body of the test case:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ cat gen.txt\ncase 2001: return \"2001\";\ncase 2002: return \"2002\";\ncase 2003: return \"2003\";<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">The small test<\/h3>\n\n\n\n<p>Rather than compiling and running the program (although I did first check it worked), instead stop the compilation process with just the generated assembler: <code>cc -S testcase.c<\/code> which creates<em> testcase.s<\/em>. I&#8217;ve removed a few framing pieces from the output, but you can see the implementation of the switch code here:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">.LC0: .string \"2001\"\n.LC1: .string \"2002\"\n.LC2: .string \"2003\"\n.LC3: .string \"N\/A\"\n switchTest:\n         .cfi_startproc\n         pushq   %rbp\n         .cfi_def_cfa_offset 16\n         .cfi_offset 6, -16\n         movq    %rsp, %rbp\n         .cfi_def_cfa_register 6\n         movl    %edi, -4(%rbp)\n         cmpl    $2003, -4(%rbp)\n         je      .L2           \/\/ Jump if equal ...\n         cmpl    $2003, -4(%rbp)\n         jg      .L3           \/\/ Jump if greater then ...\n         cmpl    $2001, -4(%rbp)\n         je      .L4\n         cmpl    $2002, -4(%rbp)\n         je      .L5\n         jmp     .L3           \/\/ Unconditional jump\n .L4:\n         movl    $.LC0, %eax\n         jmp     .L6\n .L5:\n         movl    $.LC1, %eax\n         jmp     .L6\n .L2:\n         movl    $.LC2, %eax\n         jmp     .L6\n .L3:\n         movl    $.LC3, %eax\n .L6:\n         popq    %rbp\n         ret<\/pre>\n\n\n\n<p>Translating that back into a more readable style, we get something like<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">if i == 2003 GOTO L2\nelse if i &gt; 2003 GOTO L3     \/\/ the 'jg' instruction\nelse if i == 2001 GOTO L4\nelse if i == 2002 GOTO L5\nelse GOTO L3\n\nL2: return \"2003\"\nL3: return \"N\/A\"\nL4: return \"2001\"\nL5: return \"2002\"<\/pre>\n\n\n\n<p>There&#8217;s some interesting reordering going on here, but you can see how it&#8217;s basically testing each value in turn. Which doesn&#8217;t bode well for a large switch. But let&#8217;s see what really happens.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The large test<\/h3>\n\n\n\n<p>I generated something closer to the MQRC situation using the script. There were numbers from 2000-2600 and 6100-6150 with a sprinkling of missing lines.<\/p>\n\n\n\n<p>This time the generated code looks very different. There is only a single direct comparison.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">.LC0: .string \"2000\"\n.LC1: .string \"2001\"\n....\n         subl    $2000, %eax  \/\/ Normalise to 0 base\n         <strong>cmpl    <\/strong>$4150, %eax  \/\/ The only compare instruction used\n         ja      .L2\n         movl    %eax, %eax\n         movq    .L4(,%rax,8), %rax\n         jmp     *%rax\n       \n .L4:\n         .quad   .L615\n         .quad   .L614\n         .quad   .L613\n ....\n .L615:\n         movl    $.LC0, %eax\n         jmp     .L616\n .L614:\n         movl    $.LC1, %eax\n         jmp     .L616\n....<\/pre>\n\n\n\n<p>Again doing a translation, renumbering the labels for clarity:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">t = i-2000          \/\/ normalise to a zero offset\nif t &gt; 4150 GOTO L2 \/\/ out of bounds - direct jump\nelse label = table[t]\nGOTO label \n\ntable[0] = L2000\ntable[1] = L2001\n\u2026\ntable[27] = L2 \/\/ a \"missing\" case\n\u2026\ntable[4150] = L6150\n\nL2: return \"N\/A\"\nL2000: return \"2000\"\n\u2026<\/pre>\n\n\n\n<p>What&#8217;s been done is called a <strong>jump table<\/strong>. Rather than testing every value in turn, the compiler has recognised that there is a sequence and can build a table of locations so we can step directly to the right address. The cost of returning the right string is the same regardless of the size of the switch block and the input value  (ignoring processor cache lines etc). In this case, the single jump table is large enough to cover the entire range of options from 2000-6150, with all the unused entries being set to the address of the default label. One of the aspects of the C language that makes this strategy relatively obvious is that switch statements can only be done based on integer values; other languages where matches might be made on strings or patterns could make it more complex to implement. But still not usually as bad as testing every case in turn.<\/p>\n\n\n\n<p>One further optimisation is visible here. In the small test, the generated code used the <code>jg<\/code> instruction (Jump If Greater); in the large test, there&#8217;s a <code>ja<\/code> (Jump Above) instruction. The difference between them is whether the comparison is using signed or unsigned values. If you had wondered what happened if I passed in the value 10 to the long switch, and why there was no &#8220;if less than 0&#8221; test after the subtraction, then this explains it. The expression &#8220;10 &#8211; 2000&#8221; is a lot bigger than 4150 if you ignore the sign bit on the result. So the single <code>ja<\/code> handles numbers outside the valid range at either end.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Some variations<\/h3>\n\n\n\n<p>I played with a few other scenarios. One of them was to see where <strong>gcc <\/strong>changed its behaviour from doing the direct comparison of each case into using the jump tables. It seemed that going from 4 to 5 entries was the <em>break<\/em>-point.<\/p>\n\n\n\n<p>I also did a couple of tests to investigate whether all the undefined cases got their own jump table entry when there are very large gaps in the sequences. So one generated version used numbers 200-2000, 6100-6150, and 20000-21000 in a single block, with again a few random missing entries.<\/p>\n\n\n\n<p>In that situation, <strong>gcc <\/strong>seemed to build two jump tables with a single extra comparison to work out which table to refer to. One table covered 200-6150 and the other covered 20000-21000.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Implementation differences<\/h3>\n\n\n\n<p>The fragments of assembler code here came from using <strong>gcc <\/strong>on an x64 Linux system. I also tried <strong>clang <\/strong>on the same machine. Although the code was slightly different, it showed the same fundamental pattern. I&#8217;d also expect to see similar behaviour on other platforms. Which proves to be the case using both <strong>gcc <\/strong>and <strong>xlc <\/strong>on AIX.<\/p>\n\n\n\n<p>I considered looking at the <strong>gcc <\/strong>source code to see how it made its decisions, and if it built other patterns for other kinds of distribution. But I decided that the empirical evidence shown by the assembler output was good enough.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Optimisations and Speculations<\/h3>\n\n\n\n<p>These tests were done with &#8220;unoptimised&#8221; code. I did try turning on the optimiser (<code>-O3<\/code>) but that decided to remove nearly all the code as it could tell immediately what the correct returned string was going to be. Once the program runs on real hardware, there will be further optimisations with all the tricks that processor designers come up with including speculative execution based on what might have been returned on a previous run of the same function (though perhaps less of that since SPECTRE).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Summary<\/h3>\n\n\n\n<p>Compiler writers are usually clever people! They can spot the patterns and generate suitable code. It doesn&#8217;t mean we should write deliberately inefficient code in applications, but it does mean that we don&#8217;t need to play too many tricks to get &#8220;closer&#8221; in some sense to the underlying operations. <\/p>\n<p class=\"last-modified\" style=\"border:1px solid;padding: 10px;\">This post was last updated on February 25th, 2022 at 10:03 am<\/p>","protected":false},"excerpt":{"rendered":"<p>MQ V8 introduced a header file, cmqstrc.h, that maps constants in the MQI to string values. I&#8217;ve mentioned it a few times recently, both here and in some other forums. One question came in, asking about how well that code worked. So I&#8217;ve recreated some tests I wrote back in 2015, to demonstrate what compilers &hellip; <a href=\"https:\/\/marketaylor.synology.me\/?p=1140\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;C switch statement efficiency&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[5],"tags":[117,35,20],"class_list":["post-1140","post","type-post","status-publish","format-standard","hentry","category-mq","tag-compiler","tag-ibmmq","tag-mqseries"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>C switch statement efficiency - Mark Taylor&#039;s Blog<\/title>\n<meta name=\"description\" content=\"This post looks at what C compilers do with switch statements, to see how they generate the most efficient code.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/marketaylor.synology.me\/?p=1140\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"C switch statement efficiency - Mark Taylor&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"This post looks at what C compilers do with switch statements, to see how they generate the most efficient code.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/marketaylor.synology.me\/?p=1140\" \/>\n<meta property=\"og:site_name\" content=\"Mark Taylor&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-02-15T10:59:17+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-02-25T10:03:18+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/2022\/02\/6502.png\" \/>\n<meta name=\"author\" content=\"Mark\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@marketaylor\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mark\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1140#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1140\"},\"author\":{\"name\":\"Mark\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#\\\/schema\\\/person\\\/2d6f4113ff54187023e20c20186bbb3c\"},\"headline\":\"C switch statement efficiency\",\"datePublished\":\"2022-02-15T10:59:17+00:00\",\"dateModified\":\"2022-02-25T10:03:18+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1140\"},\"wordCount\":1082,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1140#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/marketaylor.synology.me\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/6502.png\",\"keywords\":[\"compiler\",\"ibmmq\",\"mqseries\"],\"articleSection\":[\"IBM MQ\"],\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1140#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1140\",\"url\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1140\",\"name\":\"C switch statement efficiency - Mark Taylor&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1140#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1140#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/marketaylor.synology.me\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/6502.png\",\"datePublished\":\"2022-02-15T10:59:17+00:00\",\"dateModified\":\"2022-02-25T10:03:18+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#\\\/schema\\\/person\\\/2d6f4113ff54187023e20c20186bbb3c\"},\"description\":\"This post looks at what C compilers do with switch statements, to see how they generate the most efficient code.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1140#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1140\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1140#primaryimage\",\"url\":\"https:\\\/\\\/marketaylor.synology.me\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/6502.png\",\"contentUrl\":\"https:\\\/\\\/marketaylor.synology.me\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/6502.png\",\"width\":516,\"height\":766},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1140#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/marketaylor.synology.me\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"C switch statement efficiency\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#website\",\"url\":\"https:\\\/\\\/marketaylor.synology.me\\\/\",\"name\":\"Mark Taylor&#039;s Blog\",\"description\":\"Messaging, Music and Moving Around\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/marketaylor.synology.me\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#\\\/schema\\\/person\\\/2d6f4113ff54187023e20c20186bbb3c\",\"name\":\"Mark\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g\",\"caption\":\"Mark\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/marketaylor\"],\"url\":\"https:\\\/\\\/marketaylor.synology.me\\\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"C switch statement efficiency - Mark Taylor&#039;s Blog","description":"This post looks at what C compilers do with switch statements, to see how they generate the most efficient code.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/marketaylor.synology.me\/?p=1140","og_locale":"en_GB","og_type":"article","og_title":"C switch statement efficiency - Mark Taylor&#039;s Blog","og_description":"This post looks at what C compilers do with switch statements, to see how they generate the most efficient code.","og_url":"https:\/\/marketaylor.synology.me\/?p=1140","og_site_name":"Mark Taylor&#039;s Blog","article_published_time":"2022-02-15T10:59:17+00:00","article_modified_time":"2022-02-25T10:03:18+00:00","og_image":[{"url":"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/2022\/02\/6502.png","type":"","width":"","height":""}],"author":"Mark","twitter_card":"summary_large_image","twitter_creator":"@marketaylor","twitter_misc":{"Written by":"Mark","Estimated reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/marketaylor.synology.me\/?p=1140#article","isPartOf":{"@id":"https:\/\/marketaylor.synology.me\/?p=1140"},"author":{"name":"Mark","@id":"https:\/\/marketaylor.synology.me\/#\/schema\/person\/2d6f4113ff54187023e20c20186bbb3c"},"headline":"C switch statement efficiency","datePublished":"2022-02-15T10:59:17+00:00","dateModified":"2022-02-25T10:03:18+00:00","mainEntityOfPage":{"@id":"https:\/\/marketaylor.synology.me\/?p=1140"},"wordCount":1082,"commentCount":0,"image":{"@id":"https:\/\/marketaylor.synology.me\/?p=1140#primaryimage"},"thumbnailUrl":"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/2022\/02\/6502.png","keywords":["compiler","ibmmq","mqseries"],"articleSection":["IBM MQ"],"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/marketaylor.synology.me\/?p=1140#respond"]}]},{"@type":"WebPage","@id":"https:\/\/marketaylor.synology.me\/?p=1140","url":"https:\/\/marketaylor.synology.me\/?p=1140","name":"C switch statement efficiency - Mark Taylor&#039;s Blog","isPartOf":{"@id":"https:\/\/marketaylor.synology.me\/#website"},"primaryImageOfPage":{"@id":"https:\/\/marketaylor.synology.me\/?p=1140#primaryimage"},"image":{"@id":"https:\/\/marketaylor.synology.me\/?p=1140#primaryimage"},"thumbnailUrl":"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/2022\/02\/6502.png","datePublished":"2022-02-15T10:59:17+00:00","dateModified":"2022-02-25T10:03:18+00:00","author":{"@id":"https:\/\/marketaylor.synology.me\/#\/schema\/person\/2d6f4113ff54187023e20c20186bbb3c"},"description":"This post looks at what C compilers do with switch statements, to see how they generate the most efficient code.","breadcrumb":{"@id":"https:\/\/marketaylor.synology.me\/?p=1140#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/marketaylor.synology.me\/?p=1140"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/marketaylor.synology.me\/?p=1140#primaryimage","url":"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/2022\/02\/6502.png","contentUrl":"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/2022\/02\/6502.png","width":516,"height":766},{"@type":"BreadcrumbList","@id":"https:\/\/marketaylor.synology.me\/?p=1140#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/marketaylor.synology.me\/"},{"@type":"ListItem","position":2,"name":"C switch statement efficiency"}]},{"@type":"WebSite","@id":"https:\/\/marketaylor.synology.me\/#website","url":"https:\/\/marketaylor.synology.me\/","name":"Mark Taylor&#039;s Blog","description":"Messaging, Music and Moving Around","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/marketaylor.synology.me\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Person","@id":"https:\/\/marketaylor.synology.me\/#\/schema\/person\/2d6f4113ff54187023e20c20186bbb3c","name":"Mark","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/secure.gravatar.com\/avatar\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g","caption":"Mark"},"sameAs":["https:\/\/x.com\/marketaylor"],"url":"https:\/\/marketaylor.synology.me\/?author=1"}]}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/posts\/1140","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1140"}],"version-history":[{"count":16,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/posts\/1140\/revisions"}],"predecessor-version":[{"id":1180,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/posts\/1140\/revisions\/1180"}],"wp:attachment":[{"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1140"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1140"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1140"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}