<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="FeedCreator 1.8" -->
<?xml-stylesheet href="https://baszerr.eu/lib/exe/css.php?s=feed" type="text/css"?>
<rss version="2.0">
    <channel xmlns:g="http://base.google.com/ns/1.0">
        <title>BaSzErr - blog:2020:01:11</title>
        <description></description>
        <link>https://baszerr.eu/</link>
        <lastBuildDate>Tue, 05 May 2026 08:44:06 +0000</lastBuildDate>
        <generator>FeedCreator 1.8</generator>
        <image>
            <url>https://baszerr.eu/lib/exe/fetch.php?media=wiki:dokuwiki.svg</url>
            <title>BaSzErr</title>
            <link>https://baszerr.eu/</link>
        </image>
        <item>
            <title>2020-01-11_-_self-documenting_code</title>
            <link>https://baszerr.eu/doku.php?id=blog:2020:01:11:2020-01-11_-_self-documenting_code</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;self-documenting_code&quot;&gt;2020-01-11 - self-documenting code&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
throughout my carrier i went through different projects, coding styles, conventions… and documentation stiles. some better and some worse, but over time i did start extracting useful patterns out of it.
&lt;/p&gt;

&lt;p&gt;
this time i&amp;#039;d like to talk a little bit about a concept of “self-documenting code”. there is a reason to do it now – some time ago i went across an &lt;a href=&quot;https://hackaday.com/2019/03/05/good-code-documents-itself-and-other-hilarious-jokes-you-shouldnt-tell-yourself/&quot; class=&quot;urlextern&quot; title=&quot;https://hackaday.com/2019/03/05/good-code-documents-itself-and-other-hilarious-jokes-you-shouldnt-tell-yourself/&quot; rel=&quot;ugc nofollow&quot;&gt;article explaining why self-documenting code approach does not work in practice&lt;/a&gt;. the author does make a lot of valid points along the way. eg. comments stating obvious like:
&lt;/p&gt;
&lt;pre class=&quot;code C&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; temperature&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// returns temperature&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
are brain-dead in nature. no argue here.
&lt;/p&gt;

&lt;p&gt;
in my experience however, the overall conclusion of the article (“there is no such thing as self-documenting code and you&amp;#039;re only fooling yourself thinking it is so”) is wrong.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;2020-01-11 - self-documenting code&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;self-documenting_code&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-979&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;stuff_rots&quot;&gt;stuff rots&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
we all know that &lt;a href=&quot;https://en.wikipedia.org/wiki/Software rot&quot; class=&quot;interwiki iw_wp&quot; title=&quot;https://en.wikipedia.org/wiki/Software rot&quot;&gt;code rots&lt;/a&gt;. fun fact – the same thing happens with documentation! more interestingly – in my experience documentation rots WAY faster than the code itself. the reasons are fairly simple:
&lt;/p&gt;
&lt;ol&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; docs are often kept aside from code, so it is easy to miss that.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; code does not easily trace back to document, so 1 might not even be aware that what was just be changed, requires a documentation update as well.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; even if code has comments, ppl tend to skip them (&lt;abbr title=&quot;Too long; didn&amp;#039;t read&quot;&gt;TL;DR&lt;/abbr&gt;/boring/etc).&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; the more comments you have, the exponentially less the chance some1 will actually read it (note that this applies to user-facing documentation as well!).&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; when refactoring, ppl often make “quick changes here and there” to see/check some concept/improvement. this pretty much never involves comment updates, as the changes are a quick PoC by nature… and often such changes turned out for a better and, after a few adjustments, are kept… while comments remain to reflect the previous implementation.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; compilers don&amp;#039;t read comments – if these are out of sync, most likely you&amp;#039;ll either never learn that (comment was useless) or learn the hard way (eg. when documented invariant will not hold in practice – then it becomes misleading).&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
long story short – the longer docs you have, the more chance there is it will get outdated. high-level descriptions tend to be more stable (see discussion at the bottom).
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;stuff rots&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;stuff_rots&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;980-2444&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit3&quot; id=&quot;documenting&quot;&gt;documenting&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
to make things clear: aside from trivial projects – code DOES need documentation! i think it&amp;#039;s just required on a different level than comments, most of the time.
&lt;/p&gt;

&lt;p&gt;
basically you can document your project in 3 basic ways. let&amp;#039;s briefly go through them.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;documenting&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;documenting&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;2445-2724&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit4&quot; id=&quot;external_documents&quot;&gt;external documents&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
i typically tend to lean towards having top level design (TLD) document, that boils down whole (sub?)system into a 1-2 UML(-style) diagrams, showing basic interactions/dependencies and a few words of description what is where and why. &lt;abbr title=&quot;In my humble opinion&quot;&gt;IMHO&lt;/abbr&gt; this typically should take no more than a few pages (say: 1-3 pages). if you make it longer, you&amp;#039;re going into too many details. you&amp;#039;ll forgot to update it and ppl will tend not to read it anyway. and those who will – will likely get outdated pieces of information. so just comment really key aspects.
&lt;/p&gt;

&lt;p&gt;
the idea here is to provide a fast-start for new ppl joining/maintaining things. they should be able to quickly make head and tails of the system design. this is the sole purpose of this document. once it is in place, there is little chance it will ever need a change. unless major system redesign of course, but then updating 1-3 pages of text will suffice. hell – you can write that from scratch in no time! :)
&lt;/p&gt;

&lt;p&gt;
note that such documentation comes best served… as a code. think: LaTeX, markdown, etc… then it is always alongside with the code it describes, CI generates artifact out of it and is always at hand when you need it. you might even find it handy just to open as “text source” when browsing repo.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;external documents&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;external_documents&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;2725-4014&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit5&quot; id=&quot;project_structure&quot;&gt;project structure&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
so you have just read TLD. before you dive into “the real code”, you see a project&amp;#039;s overall structure: loads of directories and files. if you carefully layout these around, you provide a missing link between TLD and implementation details, hidden inside the source files.
&lt;/p&gt;

&lt;p&gt;
example layout that does NOT provide you any information:
&lt;/p&gt;
&lt;blockquote&gt;&lt;div class=&quot;no&quot;&gt;
 include/&lt;blockquote&gt;&lt;div class=&quot;no&quot;&gt;
  class1.hpp&lt;br/&gt;
  class2.hpp&lt;br/&gt;
  …&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;
 source/
&lt;/p&gt;
&lt;blockquote&gt;&lt;div class=&quot;no&quot;&gt;
  class1.cpp&lt;br/&gt;
  class2.cpp&lt;br/&gt;
  …&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;
 test/
&lt;/p&gt;
&lt;blockquote&gt;&lt;div class=&quot;no&quot;&gt;
  class1.cpp&lt;br/&gt;
  class2.cpp&lt;br/&gt;
  …&lt;/div&gt;&lt;/blockquote&gt;
&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;
example layout that DOES carry some quality pieces of information:
&lt;/p&gt;
&lt;blockquote&gt;&lt;div class=&quot;no&quot;&gt;
 FrameGrabber/&lt;blockquote&gt;&lt;div class=&quot;no&quot;&gt;
  class1.hpp&lt;br/&gt;
  class1.cpp&lt;br/&gt;
  class1.ut.cpp&lt;br/&gt;
  …&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;
 FaceDetect/
&lt;/p&gt;
&lt;blockquote&gt;&lt;div class=&quot;no&quot;&gt;
  class2.hpp&lt;br/&gt;
  class2.cpp&lt;br/&gt;
  class2.ut.cpp&lt;br/&gt;
  …&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;
 Gui/
&lt;/p&gt;
&lt;blockquote&gt;&lt;div class=&quot;no&quot;&gt;
  class3.hpp&lt;br/&gt;
  class3.cpp&lt;br/&gt;
  class3.ut.cpp&lt;br/&gt;
  …&lt;/div&gt;&lt;/blockquote&gt;
&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;
well now we see camera input module, face detection module and some &lt;abbr title=&quot;Graphical User Interface&quot;&gt;GUI&lt;/abbr&gt; – most likely some software that takes a camera stream and displays input images with detected faces. note that this fairly apparent, even though i kept shitty file names!
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;project structure&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;project_structure&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;4015-5038&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit6&quot; id=&quot;code_structure&quot;&gt;code structure&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
now it is time for me to comment what strikes me in the article that triggered this blog post. author gives “well documented” code example, that goes like this:
&lt;/p&gt;
&lt;pre class=&quot;code C&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;/**
 * Returns the temperature in tenth degrees Celsius
 * in range [0..1000], or -1 in case of an error.
 *
 * The temperature itself is set in the periodically
 * executed read_temperature() function.
 *
 * Make sure to call init_adc() before calling this
 * function here, or you will get undefined data.
 */&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;int&lt;/span&gt; get_temperature&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; temperature&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
as &lt;a href=&quot;https://en.wikipedia.org/wiki/Scott Meyers&quot; class=&quot;interwiki iw_wp&quot; title=&quot;https://en.wikipedia.org/wiki/Scott Meyers&quot;&gt;Scott Meyers&lt;/a&gt; said: &lt;em&gt;“the good &lt;abbr title=&quot;Application Programming Interface&quot;&gt;API&lt;/abbr&gt; is easy to use correctly and hard to use incorrectly”&lt;/em&gt;. the above function clearly does not meet this expectation.
&lt;/p&gt;

&lt;p&gt;
how to improve things? let&amp;#039;s get rid of the comment and replace it with something meaningful.
&lt;/p&gt;

&lt;/div&gt;

&lt;h4 id=&quot;return_int&quot;&gt;return int&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;
having &lt;em&gt;int&lt;/em&gt; with a comment? really? how about:
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;struct Temperature
{
  explicit Temperature(float value): value_{value} { /* check your invariants here: assert? exceptions? depends on context. */ }
  auto get() const { return value_; }
private:
  float value_;
};&lt;/pre&gt;

&lt;p&gt;
feeling lazy? too much writing? you can skip invariants checking and just go for:
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;struct Temperature
{
  float value_;
};&lt;/pre&gt;

&lt;p&gt;
very often this is good enough, yet now you have a real type, that is not to/from &lt;em&gt;int&lt;/em&gt; convertible and carries a meaning.
&lt;/p&gt;

&lt;p&gt;
what about an error? &lt;em&gt;std::optional&lt;/em&gt; is your friend!
&lt;/p&gt;

&lt;p&gt;
so now we have the very same function, w/o top part of the comment:
&lt;/p&gt;
&lt;pre class=&quot;code C&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;/**
 * The temperature itself is set in the periodically
 * executed read_temperature() function.
 *
 * Make sure to call init_adc() before calling this
 * function here, or you will get undefined data.
 */&lt;/span&gt;
std&lt;span class=&quot;sy0&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;me2&quot;&gt;optional&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;lt;&lt;/span&gt;Temperature&lt;span class=&quot;sy0&quot;&gt;&amp;gt;&lt;/span&gt; get_temperature&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; g_read &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; Temperature&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;g_read&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nu17&quot;&gt;10.0f&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4 id=&quot;read_temperature_part&quot;&gt;read_temperature part&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;
this is internal implementation of the function. it should not be exposed to the user of the function anyway. if you think it should, and this is important, maybe what you&amp;#039;re really after is a callback?
&lt;/p&gt;

&lt;p&gt;
so we&amp;#039;re down to:
&lt;/p&gt;
&lt;pre class=&quot;code C&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;/**
 * Make sure to call init_adc() before calling this
 * function here, or you will get undefined data.
 */&lt;/span&gt;
std&lt;span class=&quot;sy0&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;me2&quot;&gt;optional&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;lt;&lt;/span&gt;Temperature&lt;span class=&quot;sy0&quot;&gt;&amp;gt;&lt;/span&gt; get_temperature&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; g_read &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; Temperature&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;g_read&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nu17&quot;&gt;10.0f&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4 id=&quot;init_adc&quot;&gt;init_adc&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;
so we have a call sequence anti-pattern here. this is common in much of embedded code, though it can be easily addressed in multiple ways.
&lt;/p&gt;

&lt;p&gt;
first you can simply check if ADC is initialized and abort if not:
&lt;/p&gt;
&lt;pre class=&quot;code C&quot;&gt;std&lt;span class=&quot;sy0&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;me2&quot;&gt;optional&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;lt;&lt;/span&gt;Temperature&lt;span class=&quot;sy0&quot;&gt;&amp;gt;&lt;/span&gt; get_temperature&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  ASSERT&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; SOME_SPECIAL_REGISTER &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt; ADC_ENABLED &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; g_read &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; Temperature&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;g_read&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nu17&quot;&gt;10.0f&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
second way is to just enable it, if it is not:
&lt;/p&gt;
&lt;pre class=&quot;code C&quot;&gt;std&lt;span class=&quot;sy0&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;me2&quot;&gt;optional&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;lt;&lt;/span&gt;Temperature&lt;span class=&quot;sy0&quot;&gt;&amp;gt;&lt;/span&gt; get_temperature&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; not &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;SOME_SPECIAL_REGISTER &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt; ADC_ENABLED&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    enable_adc&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    wait_for_first_read&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; g_read &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; Temperature&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;g_read&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nu17&quot;&gt;10.0f&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
third way is to make it a class, so that you&amp;#039;re not able to call &lt;em&gt;get_temperature()&lt;/em&gt; without initializing ADC first:
&lt;/p&gt;
&lt;pre class=&quot;code C&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;struct&lt;/span&gt; AdcTemperature
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  AdcTemperature&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    enable_adc&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    wait_for_first_read&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
  ~AdcTemperature&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    disble_adc&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
  AdcTemperature&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;AdcTemperature const&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; delete&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  AdcTemperature&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt; operator&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;AdcTemperature const&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; delete&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
  std&lt;span class=&quot;sy0&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;me2&quot;&gt;optional&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;lt;&lt;/span&gt;Temperature&lt;span class=&quot;sy0&quot;&gt;&amp;gt;&lt;/span&gt; get_temperature&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt;
  &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; g_read &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
      &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; Temperature&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;g_read&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nu17&quot;&gt;10.0f&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
if you have some super-tiny µC (like 64B of RAM, or similar), note that the class can in fact be ref-counted and/or singleton, to avoid overhead of having &lt;em&gt;*this&lt;/em&gt; pointer around.
&lt;/p&gt;

&lt;p&gt;
we&amp;#039;re not left w/o any need of a comment. pick your favorite way to get there! :) code is now self-documenting and as a free-lunch it is now not possible to use it incorrectly! in the original code just think how often ppl would forget to check if temperature is not -1 and instead just use it directly in some computations. same goes for &lt;em&gt;init_adc()&lt;/em&gt; part.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;code structure&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;code_structure&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:6,&amp;quot;range&amp;quot;:&amp;quot;5039-9195&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit7&quot; id=&quot;code_comments&quot;&gt;code comments&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
inside the code – most of the time there should be no comments. if you write a comment, you basically say that you failed to express yourself with the code and thus there is a good chance that you&amp;#039;ll also fail to do this in plain text (see: &lt;a href=&quot;https://en.wikipedia.org/wiki/Robert C. Martin&quot; class=&quot;interwiki iw_wp&quot; title=&quot;https://en.wikipedia.org/wiki/Robert C. Martin&quot;&gt;Uncle Bob&lt;/a&gt;).
&lt;/p&gt;

&lt;p&gt;
there however ARE places, where comment is meaningful. one of the best examples i have seen recently was in my previous project. i got a code review, that involved &lt;a href=&quot;https://en.wikipedia.org/wiki/Wavelet Tree&quot; class=&quot;interwiki iw_wp&quot; title=&quot;https://en.wikipedia.org/wiki/Wavelet Tree&quot;&gt;wavelet tree&lt;/a&gt;. nodes were packed into an array (private class member) and it was commented with nodes order, designating how the tree is build. i do not have the code in front of me now, but it was sth like this:
&lt;/p&gt;
&lt;pre class=&quot;code C&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;/*
 *     ACTNG
 *    /    \
 *   AC    TNG
 *  / \    / \
 * A   C  TN  G
 *       / \
 *      T   N
 */&lt;/span&gt;
stuff wt&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
just look how much pieces of information this little &lt;abbr title=&quot;American Standard Code for Information Interchange&quot;&gt;ASCII&lt;/abbr&gt; art adds! think how hard it would be to reasonably encode it into code itself.
&lt;/p&gt;

&lt;p&gt;
comments are good, if used with care. if you read the code, and spot a single comment – you&amp;#039;ll read it for sure. if you have a comment every 2nd line – no1 will. ever.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;code comments&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;code_comments&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:9,&amp;quot;secid&amp;quot;:7,&amp;quot;range&amp;quot;:&amp;quot;9196-10346&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit8&quot; id=&quot;kung-fu_levels&quot;&gt;kung-fu levels&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
self-documenting code is not avoiding documentation. it is more about making things in such a way, that documentation is in the compilation loop.
&lt;/p&gt;
&lt;ol&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; writing code is generally hard.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; writing code that works correctly is even harder.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; writing understandable and/or maintainable code is way harder.&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
you can think of it as climbing a ladder of difficulty. first you get “sth that mostly works”, then you get “sth that works stable” and then you make it so that others can maintain/understand it as well. writing self documenting code falls into 3rd category – i.e. it is really hard and most programmers don&amp;#039;t reach that point before “senior level” (and some never – life). ppl heavily commenting code are typically around 2nd level (1st level often has neither comments nor order ;)).
&lt;/p&gt;

&lt;p&gt;
note that an excellent feedback loop regarding your coding style + code/documentation balance is a code review. during this process, another human being tries to understand what you meant. getting code reviews from some1 more experienced than yourself is of a great benefit here.
&lt;/p&gt;

&lt;p&gt;
btw: i&amp;#039;ve recently added a note to my CV, regarding my ambition/goal:
&lt;/p&gt;
&lt;blockquote&gt;&lt;div class=&quot;no&quot;&gt;
 Being a least-competent member of a high-end professionals team.&lt;/div&gt;&lt;/blockquote&gt;

&lt;p&gt;
it&amp;#039;s always good to be surrounded by ppl you can learn from.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;kung-fu levels&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;kung-fu_levels&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:10,&amp;quot;secid&amp;quot;:8,&amp;quot;range&amp;quot;:&amp;quot;10347-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Tue, 15 Jun 2021 20:09:26 +0000</pubDate>
        </item>
    </channel>
</rss>
