{"id":9341,"date":"2020-07-13T09:09:15","date_gmt":"2020-07-13T13:09:15","guid":{"rendered":"https:\/\/blogs.mentor.com\/colinwalls\/?p=9341"},"modified":"2026-03-26T17:00:33","modified_gmt":"2026-03-26T21:00:33","slug":"embedded-code-clear-or-clever","status":"publish","type":"post","link":"https:\/\/blogs.sw.siemens.com\/embedded-software\/2020\/07\/13\/embedded-code-clear-or-clever\/","title":{"rendered":"Embedded code: clear or clever?"},"content":{"rendered":"<p>When developing embedded code, there are various priorities. Top of the list, obviously, is delivering the required functionality and performance. This can be challenging enough. A key requirement is a clear, unambiguous and stable specification. However, at a lower level, the code developer has lots of everyday decisions to make around a number of sometime opposing priorities \u2026<!--more--><\/p>\n<p>The design of desktop applications is driven by a single criterion: user satisfaction. So, given the design [the user interface in particular] is up to scratch, the main thing is speed. Embedded systems are different as there may or may not be a UI; the device may or may not be real time; cost can be a big issue. The list goes on, but ultimately it results in some prioritization when implementing the code:<\/p>\n<ol>\n<li>code for highest performance<\/li>\n<li>code for predictable performance [deterministic]<\/li>\n<li>code for minimum size<\/li>\n<li>code for minimum power consumption<\/li>\n<li>code for maintainability<\/li>\n<\/ol>\n<p>Of these, 1-4 are often in tension and finding the balance is the challenge and that depends on the application. To a significant extent these factors are influenced by the higher-level aspects of the implementation: using a <a href=\"https:\/\/www.mentor.com\/embedded-software\/nucleus\/\" target=\"_blank\" rel=\"noopener noreferrer\">real-time operating system<\/a>, with a <a href=\"https:\/\/www.mentor.com\/embedded-software\/nucleus\/power-management\" target=\"_blank\" rel=\"noopener noreferrer\">power-management framework<\/a> perhaps; maybe implementing a <a href=\"https:\/\/www.mentor.com\/embedded-software\/multicore\" target=\"_blank\" rel=\"noopener noreferrer\">multicore design<\/a>. Beyond that, understanding the fine tuning of code generation is worthwhile, as a compiler generally knows best how to achieve many of these goals.<\/p>\n<p>The outlier is #5. Software development is expensive. More time is spent maintaining code [fixing, updating and augmenting] than developing new applications. This means that any effort spent making the code clearer is an investment in the future. There are two bonuses: clearer code is generally more reliable, which means that it needs less maintenance; code written for clarity is very rarely slower or larger than a less clearly expressed algorithm.<\/p>\n<p>Writing clear, maintainable code is possible in most programming languages. Although this may be challenging in, say, Forth of LISP. It is [very] easy to write highly obfuscated code in C, but writing clear code is not difficult. There are numerous coding style guides around and even using a programming standard like MISRA C, that is designed to help make code reliable, tends to lead to more maintainable code. To some extent, a \u201chigher level\u201d language may be helpful, as algorithms may be expressed more naturally. C++ is an obvious possibility. Here is an example:<\/p>\n<p>If an application uses complex numbers, a means to represent them and operate on them is required. In C, a structure makes sense:<\/p>\n<pre><strong>struct cx<\/strong>\n<strong>{<\/strong>\n<strong>   float real;<\/strong>\n<strong>   float imag;<\/strong>\n<strong>};<\/strong><\/pre>\n<p>Then, we can create two variables, initialize them and add one to the other thus:<\/p>\n<pre><strong>struct cx x, y;<\/strong>\n\n<strong>x.real = 1.0;<\/strong>\n<strong>x.imag = 2.0;<\/strong>\n\n<strong>y.real = 3.0;<\/strong>\n<strong>y.imag = 4.0;<\/strong>\n\n<strong>x.real += y.real;<\/strong>\n<strong>x.imag += y.imag;<\/strong><\/pre>\n<p>This is reasonably clear and succinct, but can C++ do better? I would say the answer is yes. We can define a class to represent the data, which can include a constructor function to take care of initialization and a function to perform the addition:<\/p>\n<pre><strong>class cx<\/strong>\n<strong>{<\/strong>\n<strong>   float real;<\/strong>\n<strong>   float imag;<\/strong>\n<strong>public:<\/strong>\n<strong>   cx(float r, float i)<\/strong>\n<strong>   {<\/strong>\n<strong>      real = r;<\/strong>\n<strong>      imag = i;<\/strong>\n<strong>   }<\/strong>\n<strong>   void add(cx n)<\/strong>\n<strong>   {<\/strong>\n<strong>      real += n.real;<\/strong>\n<strong>      imag += n.imag;<\/strong>\n<strong>   }<\/strong>\n<strong>};<\/strong><\/pre>\n<p>This enables complex variables to be set up and added thus:<\/p>\n<pre><strong>cx x(1.0, 2.0), y(3.0, 4.0);<\/strong>\n\n<strong>x.add(y);<\/strong><\/pre>\n<p>Although this is neater\/clearer that C, there is room for improvement. The <strong>add()<\/strong> function can be replaced by an operator overloading function [which has identical code]:<\/p>\n<pre><strong>void operator+=(cx n)<\/strong>\n<strong>{<\/strong>\n<strong>   real += n.real;<\/strong>\n<strong>   imag += n.imag;<\/strong>\n<strong>}<\/strong><\/pre>\n<p>The result is handling of complex numbers in a very natural way:<\/p>\n<pre><strong>cx x(1.0, 2.0), y(3.0, 4.0);<\/strong>\n\n<strong>x += y;<\/strong><\/pre>\n<p>These features of C++ can certainly help clarify code, particularly the operator overloading. However, a word of warning. It is essential to maintain the intuitive functionality of the operator, as I have here. The <strong>+=<\/strong> does exactly what the reader of the code would expect. Many years ago, when I was first learning C++, I read a book that demonstrated the overloading of the <strong>+<\/strong> operator, which would result in a statement like this:<\/p>\n<pre><strong>x + y;<\/strong><\/pre>\n<p>This would add <strong>y<\/strong> to <strong>x<\/strong>. Go figure.<\/p>\n<p><a href=\"http:\/\/www.linkedin.com\/in\/colinwalls\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6579\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/linkedin.png\" alt=\"\" width=\"40\" height=\"40\"><\/a><a href=\"https:\/\/twitter.com\/colin_walls\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6583\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/twitter.png\" alt=\"\" width=\"40\" height=\"40\"><\/a><a href=\"https:\/\/www.facebook.com\/colinwalls.author\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6591\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/facebook.png\" alt=\"\" width=\"40\" height=\"40\"><\/a><a href=\"http:\/\/blogs.mentor.com\/colinwalls\/\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-6599\" src=\"http:\/\/s3-blogs.mentor.com\/colinwalls\/files\/2014\/01\/wordpress.jpg\" alt=\"\" width=\"44\" height=\"44\"><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>When developing embedded code, there are various priorities. Top of the list, obviously, is delivering the required functionality and performance&#8230;.<\/p>\n","protected":false},"author":71677,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spanish_translation":"","french_translation":"","german_translation":"","italian_translation":"","polish_translation":"","japanese_translation":"","chinese_translation":"","footnotes":""},"categories":[1],"tags":[313,339,300,304,374,378,504,309,478],"industry":[],"product":[],"coauthors":[],"class_list":["post-9341","post","type-post","status-publish","format-standard","hentry","category-news","tag-c","tag-development-tools","tag-embedded-software","tag-nucleus","tag-nucleus-os","tag-nucleus-rtos","tag-power-management","tag-rtos","tag-sourcery-codebench"],"_links":{"self":[{"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts\/9341","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/users\/71677"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/comments?post=9341"}],"version-history":[{"count":2,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts\/9341\/revisions"}],"predecessor-version":[{"id":9400,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/posts\/9341\/revisions\/9400"}],"wp:attachment":[{"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/media?parent=9341"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/categories?post=9341"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/tags?post=9341"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/industry?post=9341"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/product?post=9341"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/embedded-software\/wp-json\/wp\/v2\/coauthors?post=9341"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}