Archive for the ‘Uncategorized’ Category

C’s goto Keyword: Should we Use It or Lose It?

Wednesday, June 6th, 2018 Michael Barr

In the 2008 and 2013 editions of my bug-killing Embedded C Coding Standard, I included this rule:

Rule 1.7.c. The goto keyword shall not be used.

Despite this coding standard being followed by about 1 in 8 professional embedded systems designers, none of us at Barr Group have heard any complaints that this rule is too strict. (Instead we hear lots of praise for our unique focus on reducing intra-team stylistic arguments by favoring above all else C coding rules that prevent bugs.)

However, there exist other coding standards with a more relaxed take on goto. I’ve thus been revisiting this (and related) rules for an updated 2018 edition of the BARR-C standard.

Specifically, I note that the current (2012) version of the MISRA-C Guidelines for the Use of the C Programming Language in Critical Systems merely advises against the use of goto:

Rule 15.1 (Advisory): The goto statement should not be used

though at least the use of goto is required to be appropriately narrowed:

Rule 15.2 (Required): The goto statement shall jump to a label declared later in the same function

Rule 15.3 (Required): Any label referenced by a goto statement shall be declared in the same block, or in any block enclosing the goto statement

Generally speaking, the rules of the MISRA-C:2012 standard are either the same as or stricter than those in my BARR-C standard. In addition to overlaps, they have more and stricter coding rules and we add stylistic advice. It is precisely because MISRA-C’s rules are stricter and only BARR-C includes stylistic rules that these two most popular embedded programming standards frequently and easily combined.

Which all leads to the key question:

Should the 2018 update to BARR-C relax the prior ban on all use of goto?

According to the authors of the C programming language, “Formally, [the goto keyword is] never necessary” as it is “almost always easy to write code without it”. They go on to recommend that goto “be used rarely, if at all.”

Having, in recent days, reviewed the arguments for and against goto across more than a dozen C programming books as well as other C/C++ coding standards and computer science papers, I believe there is just one best bug-killing argument for each side of this rule. And I’ll have to decide between them this week to keep the new edition on track for a June release.

Allow goto: For Better Exception Handling

There seems to be universal agreement that goto should never be used to branch UP to an earlier point in a function. Likewise, branching INTO a deeper level of nesting is a universal no-no.

However, branching DOWN in the function and OUT to an outer level of nesting are often described as powerful uses of the goto keyword. For example, a single goto statement can be used to escape from two or more levels of nesting. And this is not a behavior that can be done with a single break or continue. (To accomplish the same behavior without using goto, one could, e.g., set a flag variable in the inner block and check it in each outer block.)

Given this, the processing of exceptional conditions detected inside nested blocks is a potentially valuable application of goto that could be implemented in a manner compliant with the three MISRA-C:2012 rules quoted above. Such a jump could even proceed from two or more points in a function to a common block of error recovery code.

Because good exception handling is a property of higher reliabilty software and is therefore a potential bug killer, I believe I must consider relaxing Rule 1.7.c in BARR-C:2018 to permit this specific use of goto. A second advantage of relaxing the rule would be increasing the ease of combining rules from MISRA-C with those from BARR-C (and vice versa), which is a primary driver for the 2018 update.

Ban goto: Because It’s Even Riskier in C++

As you are likely aware, there are lots of authors who opine that use of goto “decreases readability” and/or “increases potential for bugs”. And none other than Dijkstra (50 years ago now!) declared that the “quality of programmers is [inversely proportional to their number] of goto statements”.

But–even if all true–none of these assertions is a winning argument for banning the use of goto altogether vs. the above “exception handling exception” suggested by the above.

The best bug-killing argument I have heard for continued use of the current Rule 1.7.c is that the constructors and destructors of C++ create a new hazard for goto statements. That is, if a goto jumps over a line of code on which an object would have been constructed or destructed then that step would never occur. This could, for example, lead to a very subtle and difficult type of bug to detect–such as a memory leak.

Given that C++ is a programming language intentionally backward compatible with legacy C code and that elsewhere in BARR-C there is, e.g., a rule that variables (which could be objects) should be declared as close as possible to their scope of use, relaxing the existing ban on all use of goto could forseeably create new hazards for the followers of the coding standard who later migrate to C++. Indeed, we already have many programmers following our C coding rules while crafting C++ programs.

So what do you think? What relevant experiences can bring to bear on this issue in the comments area below? Should I relax the ban on goto or maintain it? Are there any better (bug-killing) arguments for or against goto?

The Rise of the Full Stack Developers

Monday, May 28th, 2018 Michael Barr

I’m a connector within our embedded systems design community and, so, my LinkedIn account has more than 15,000 connections. Which is where I recently started to spot what appears to be an emerging industry trend: so-called “full stack developers” have begun to enter the embedded software realm.

While many self-identified firmware developers and embedded programmers have come up to the field from the electronics side, often cutting their teeth in electrical engineering and digital design first, a full stack developer is a software engineer who works at all layers of a complex software system. For example, many full stack developers create websites that connect to relational databases and/or cloud-hosted APIs. In the process a single such developer might write code in languages ranging from JavaScript and Ruby to Python, C, and shell scripts to SQL and C#. All in the same month!

To accomplish this, a full stack developer need not be an expert in all of those languages nor software layers. Rather, he or she should be an adaptable sort who is able to copy and paste then tweak the necessary bits of “glue code” to connect together various commercial, open-source, and bespoke software packages running on a variety of operating systems across what is effectively a distributed computing platform. By necessity, things may not always work right the first or even second time; but the full stack developer chips away at all of those interfaces iteratively until the requirements are met–more or less.

What seems to be changing now is that embedded systems are being added to the “full stack” mix. Other software developers are no longer afraid to interface with or alter our systems and increasingly view IoT and other connected embedded systems as just another part of their project to be integrated as quickly as possible. I’m seeing evidence of this in the increase of developers with “full stack” in their job titles and expertise summaries within my network and communicating with us over at Barr Group.

Of course, when a full stack developer is not an expert in uniquely embedded systems challenges (e.g., the Top 10 Causes of Nasty Embedded Software Bugs) or does not exercise due care, this could increase the risks of failures of safety- and mission-critical systems.

What do you think? Are you a full stack developer working with embedded systems? Comment below.

C: The Immortal Programming Language

Thursday, February 22nd, 2018 Michael Barr

Barr Group’s 2018 Embedded Systems Safety & Security Survey is now closed and I am in the midst of analyzing the data. This year a portion of my analysis is focused on multi-year trends. One trend that really stands out to me is that the C programming language refuses to give up the ghost.

A longitudinal study of survey data spanning almost a decade and a half shows that C remains the primary programming language of embedded software. Remarkably, in that time C has actually gained market share from 50% to about 70%–at the expense of assembly, C++, and Java.

The graph below shows the relevant data from 2005 through 2018. The first decade of this data is drawn from annual surveys published by the publishers of Embedded.com with the most recent data coming from Barr Group’s annual survey. Each of these surveys of embedded systems designers phrased the relevant question similarly, either “My current embedded project is programmed mostly in [pick one]” or “What is the primary programming language for your current project? [pick one]”.

Language Use Trend Plot

It makes total sense that the use of assembly language as a primary programming language is falling. The last time I wrote an embedded program mostly in assembly was about twenty years ago. Of course, there will always be some low level code that needs to be written in the native language of the machine–if only to bring up the higher-level language execution and for drivers and kernel code. But with inexpensive (and mostly 32-bit ARM-based) microcontrollers increasingly at the heart of our systems there’s no sense wasting time coding the application code in assembly.

We can attribute about 7 percentage points of the growth in use of C to the reduction in use of assembly during these years. This trend has helped use of C grow to about 60%.

But what’s also been happening in this time is that C++ has failed to capitalize on earlier gains. The peak year for C++ use was apparently 2006, when it had 33% share. Use of C++ as the primary language has since fallen and thus added about 10 percentage points to use of C.

I didn’t include Java in the graph, but it’s use has been less common than assembly in every survey year, with high points of 3% and now down around 1% the last three years. And no other language has emerged to maintain greater than 1% share.

What I make of all of this is that C remains the most cost-effective way to write embedded software. In hindsight, object-oriented languages have been tried but failed to establish their value to most programmers. C++ is a player but looks unlikely to ever eclipse its namesake.

What do you see in the data?

C’s strcpy_s(): C11’s More Secure Version of strcpy()

Thursday, August 31st, 2017 Michael Barr

Buffer overflows are a well-known port of entry for hackers and attackers of computerized systems. One of the easiest ways to create a buffer overflow weakness in a C program has long been to rely on the strcpy() function of the C standard library to overwrite data.

There’s a decent explanation of the problem at http://www.thegeekstuff.com/2013/06/buffer-overflow/. But the nutshell version is that you have a buffer of size X somewhere in memory that your code uses strcpy() to overwrite new nul-terminated strings. If an attacker can somehow feed a string longer than X bytes to your function then data beyond the bounds of the original array will be overwritten too: thereby rewriting code or data that serves some other purpose.

You should know that the new C11 update to the C programming language provides for a replacement “safe” version of this function, which is named strcpy_s(). The parameter lists and return types differ:

char *strcpy(char *strDestination, const char *strSource);

versus:

errno_t strcpy_s(char *strDestination, size_t numberOfElements, const char *strSource);

The new “numberOfElements” parameter is used by strcpy_s() to check that the strSource is not bigger than the buffer. And, when there is a problem, an error code is returned.

The Microsoft Developer Network website is one source of additional detail on this and other of C11’s “safe” functions.

Real Men [Still] Program in C

Wednesday, March 29th, 2017 Michael Barr

It’s hard for me to believe, but it’s been nearly 8 years since I wrote the popular “Real Men Program in C” blog post (turned article). That post was prompted by a conversation with a couple of younger programmers who told me: “C is too hard for programmers of our generation to bother mastering.”

I ended then:

If you accept [] that C shall remain important for the foreseeable future and that embedded software is of ever-increasing importance, then you’ll begin to see trouble brewing. Although they are smart and talented computer scientists, [younger engineers] don’t know how to competently program in C. And they don’t care to learn.

But someone must write the world’s ever-increasing quantity of embedded software. New languages could help, but will never be retrofitted onto all the decades-old CPU architectures we’ll continue to use for decades to come. As turnover is inevitable, our field needs to attract a younger generation of C programmers.

What is the solution? What will happen if these trends continue to diverge?

Now that a substantial period of years has elapsed, I’d like to revisit two key phrases from that quote: Is C still important? and Is there a younger generation of C programmers? There’s no obvious sign of any popular “new language” nor of any diminution of embedded systems.

Is C Still Important?

The original post used survey data from 1997-2009 to establish that C was (through that entire era) the dominant programming language for embedded systems. The “primary” programming languages used in the final year were C (62%), C++ (24%), and Assembly (5%).

As the figure below shows (data from Barr Group‘s 2017 Embedded Systems Safety & Security Survey), C has now consolidated its dominance as the lingua franca of embedded programmers: now at 71%. Use of C++ remains at about the same level (22%) while use of assembly as the primary language has basically disappeared.

Primary Programming Language

Conclusion: Obviously, C is still important in embedded systems.

Is There a Younger Generation of C Programmers?

The next figure shows the years of paid, professional experience of embedded system designers (data from the same source). Unfortunately, I don’t have data from that older time period about the average ages of embedded programmers. But what looks potentially telling about this is that the average years of experience of American designers (two decades) is much higher than the averages in Europe (14 years) and Asia (11). I dug into the data on the U.S. engineers a bit and found that the experience curve was essentially flat, with no bigger younger group like in the worldwide data.

Years of Experience

Conclusion: The jury is still out. It’s possible there is already a missing younger generation in the U.S., but there also seems to be some youth coming up into our field in Asia at least.

It should be really interesting to see how this all plays out in the next 8 years. I’m putting a tickler in my to-do list to blog about this topic again then!

Footnote: Same as last time, I’m not excluding women. There are plenty of great embedded systems designers who are women–and they mostly program in C too, I presume.