As technology advances, customer expectations rise accordingly. Embedded devices are becoming smarter, and the associated systems and software increasingly complex, even as development timelines shorten. Developing high-quality software swiftly is crucial for product success. This blog discusses systematic approaches to improve code quality in daily development.
Code quality measures the effectiveness of code, distinguishing 'good' code (high quality) from 'bad' code (low quality). While no single definition of code quality exists, it is commonly assessed through several metrics:
Improving code quality is an ongoing practice, not a one-time task. Here are some effective strategies:
Improving code quality in the daily development phase enables early bug detection and fixes, significantly reducing the cost of fixes. The following is a picture of bug injection, detection, and the cost to fix the bug from Capers Jones's book "Applied Software Measurement: Global Analysis of Productivity and Quality". Two things are very salient from the picture:
Finding a late bug is more costly because that defect skews your software release metrics. The later you discover the bug, the more testing you have to put into the system to make it achieve your release metrics. Therefore, improving code quality in the daily development (coding) phase can reduce the number of defects that are initially injected into the code as well as help find other bugs as early as possible. This twin edge of code quality dramatically reduces the cost of software bugs for your project.
Improving code quality can seem daunting at first, but when you use quality tools, the process becomes much easier. Here are some tips to help you quickly improve your code quality.
Achieving 0 Errors, Warnings during build is crucial. Errors will fail the build, but warnings, while not failing the build, may indicate potential hidden bugs.
The following is a classic compiler warning: the comparison operator == should be used instead of the assignment operator =:
Rebuild after modification: 0 Errors, 0 Warnings:
After a successful build with 0 Errors, 0 Warnings, it's highly recommended to perform static code analysis. Static code analysis checks the code for common pitfalls that trip up developers during their daily coding. Moreover, static code analysis is simple if you are using quality tools.
In IAR Embedded Workbench, you just need to select the corresponding C-STAT checks first:
Then, you can perform static code analysis on the entire project using C-STAT:
You can also perform static code analysis on a single file using C-STAT:
After the analysis is completed, the corresponding C-STAT Messages window will display the corresponding results. Double-click the corresponding information to see its location in your source code:
Another handy feature of the IAR C-STAT tool is its context-sensitive help. You can highlight one of the violations in the C-STAT Messages window and press F1 to get more information on the violation. This includes a detailed description of the violation, the coding standards that list this violation, a Severity/ Certainty matrix, and – most importantly – examples that show you what the bug looks like in code and how to correct that example to fix the bug. Having examples like this can make it easier to isolate and correct the issue in your own code:
Using the information from the context-sensitive help, you surmise that you need to change 4u in the code to (int32_t) 4. Once the change is made, we then perform static code analysis again. The previous violation has been fixed:
A case study at Google and published by ACM showed that getting code feedback is just as important as the actual feedback itself. When the feedback is instantaneous (or nearly so), developers will treat that feedback as something that needs to be addressed 74% of the time. If the feedback was delayed (due to the fact that it was part of a nightly build, for example), then that percentage fell to 21%. The authors believe that it is due to the “survivor effect” of code, meaning that admitting the issue is indeed a bug has a deleterious impact on their release metrics. IAR C-STAT enables developers to find and fix these bugs while desk-checking their code (i.e., before it goes into a build process), making it seem like the bug never happened from the perspective of release metrics.
After static code analysis, it is highly recommended to do unit testing as static code analysis can only check whether the code follows relevant coding standards and unit testing is needed to test the function of the code.
IAR itself does not provide unit testing tools. IAR has a bevy of partners that provide such unit testing tools. Sometimes, defects can manifest only during runtime and while modules call one another. To help test these situations, IAR C-RUN runtime checking can help find some potential issues during unit testing.
In IAR Embedded Workbench, you just need to select the corresponding C-RUN runtime checking rules:
After rebuilding, the compiler will automatically insert the corresponding test code wherever a potential failure occurs.
When running, C-RUN will detect your code fails the inserted checks. For example, the following C-RUN Messages prompt that there is an access out-of-bounds violation:
The size of the corresponding array is 4, but [4] represents the 5th array element. This causes the access out-of-bounds violation. After modifying the code, we can run the test again to see that our code appears to be running without any violations:
After unit testing, it is highly recommended to invite peers to do a code review. It is recommended to do the code review after building with 0 Errors, 0 Warnings, performing static code analysis, and executing unit testing in order to improve the efficiency of code review. Human reviews are the most expensive type of code test, so you should only employ this type of test on properly vetted code that passes all the previously mentioned tests.
After code review, it is recommended to upload the code to the server for CI/CD to do automated build, static code analysis and unit testing.
IAR provides the corresponding automation tool IAR Build Tools, which can perform automated build, static code analysis and download & debugging (for unit testing) through the command line:
A focus on code quality is becoming more common with customers as early adherents to the code quality bandwagon have proven how they can increase developer productivity while simultaneously delivering projects on time and under budget. However, not everyone has discovered these best practices:
This blog uses IAR Embedded Workbench and IAR Build Tools (including C-STAT static code analysis and C-RUN runtime checking) as examples to introduce how developers can improve code quality in daily development. It should be noted that the IAR Embedded Workbench and IAR Build Tools (including C-STAT static code analysis and runtime checking) in the blog are only tool examples, and the approaches in the blog are also applicable to other tools.
Choosing the corresponding tools is crucial, but even more importantly, developers need to make full use of their selected tools in daily development to improve code quality. Since most bugs are introduced during the daily development (coding) phase, the earlier the bug is found, the easier it is to fix and the lower the fix cost; conversely, the later the bug is found, the harder it is to fix and the higher the fix cost.
Enhance your embedded projects with advanced development solution. Explore IAR Embedded Workbench for Arm, IAR Build Tools, and ensure code quality with C-STAT static code analysis and C-RUN runtime checking.