What Is Continuous Code Inspection?
Continuous code inspection means constantly scanning your code for defects. It’s especially important for DevOps and Agile development — where traditional code inspections aren’t enough.
Code Inspections Improve Quality
Code inspections are typically formal code reviews. The goal is to prevent defects — and detect them earlier. And code inspections can detect up to 90% of defects at a fraction of the cost of other techniques.
Code Inspection and Testing
Testing verifies functionality and improves software quality. But testing is best paired with code inspections.
If your code is complex (like most embedded systems), it may not be fully testable. A code inspection, however, can find defects at the code level.
Testing is expensive if you have to go through it over and over again. By minimizing defects during code inspections, you can make your testing efforts more efficient.
Even with automated testing, it takes time to verify functionality. By resolving defects at the code level, you’ll be able to test functionality faster.
But Traditional Code Inspections Aren’t Agile
Code inspections can strain resources early in the development process. This can be a problem for Agile development teams who don’t want to be burdened with code inspections.
They see code inspections with:
- No measurable benefit.
- No follow through.
- Lack of buy in from programmers.
- Fear that reviews will be too confrontational.
- Dread that reviews will be boring.
But continuous code inspections are different.
Continuous Code Inspection for a DevOps World
Continuous code inspections are a better fit for a DevOps world. To inspect code continuously, you'll need to constantly scan it for defects at every stage of production.
Important Code Inspection Criteria
Code inspections need well-defined criteria — especially continuous code inspections. And, of course, these criteria should be specific and measurable.
Code should be checked according to criteria to ensure requirements are met. These include:
- Functional requirements that describe the behaviors needed to support user needs.
- Structural requirements that identify the attributes needed for system integrity.
There can be some overlap between functional and structural requirements. For instance, reliability and efficiency are important for both functional and structural requirements.
Here are some examples of code inspection criteria.
These are likely run-time errors that can cause unwanted behavior. It's best to identify these before your program runs. You can do this with static analysis.
Here are some examples of run-time defects:
- Initialization (e.g. using the value of unset data).
- Arithmetic operations (e.g. operations on signed data resulting in overflow).
- Arrays and pointer operations (e.g. array out of bounds, dereferencing NULL pointers).
- Resource and API usage (e.g. memory leaks, invalid pointer arguments to a function).
- Redundancy (e.g. values assigned to identifiers never used, invariant conditions).
- Control flow (e.g. unreachable code, infinite loops).
Preventative practices can help you avoid error-prone or confusing code.
These practices cover:
- Declarations and scoping (e.g. function default arguments, constness, access protection).
- Limitations on preprocessor (e.g. warning include guards and notes on macro usage).
- Safe typing (e.g. warnings on type casting, assignments, operations).
- Efficiency (e.g. notes on better paradigms or coding alternatives).
- Design problems (e.g. preventive notes, potential problem warnings, resource usage).
- Maintenance (e.g. readability and understandability notes and warnings).
- Code structure (e.g. analysis of switch statements, unstructured statements).
Complex software is hard to maintain. Setting acceptable complexity thresholds based on software metrics can ensure software is easier to maintain.
You can use the following metrics:
- Lines of code counts.
- Comment-to-code ratio.
- Function call counts.
- Decision-based cyclomatic complexity.
- Class-based design complexity measures.
The C and C++ languages are committed to maintaining backward compatibility. But they also emphasize a close binding to machine models. This can cause subtle and hard-to-find defects. Using a coding standard can help you find them.
In-house coding standards are often just style, layout, or naming rules and guidelines. These conventions are important for maintainability. However, they don’t often impact code integrity. Using a proven coding standard is better for improving quality.
Portable code can handle a range of environment changes, including:
- Machine architecture (data sizes & alignments).
- Compiler versions with improved language compliance.
- Different target compilers.
- Libraries with different behaviors.
5 Steps to Improve Your Code Inspection Process
There are five keys to a successful code inspection process. You can use them to adapt your code inspection process to a DevOps world.
1. Involve Stakeholders
Quality should matter to everyone. It’s one of the staples of DevOps.
Developers struggle daily with quality issues on source code. Managers need a meaningful gauge on the structural quality of the code. And it’s important to have insight into overall quality early on — instead of risking issues being detected by customers.
As Dr. Edwards Deming says, quality should be built into the product from the beginning. And that can be done through collaboration — both in coding and in code inspections.
3. Analyze Metrics
Continuous improvement is important. And you can’t improve what you can’t measure. So, it’s important to analyze metrics.
It’s not just about finding and fixing defects early and often. It’s about improving the process of finding them.
Your goal should be to develop advanced metrics. Then you’ll more accurately anticipate software quality as it is being developed.
4. Recognize Exceptions
Sometimes there are exceptions to the rule.
In an ideal world, code is 100% compliant to every rule in a coding standard. The reality is different.
Let’s say an organization has a coding standard rule that defends against divide by zeros. What happens when a function violates the rule.
The developer argues “we have to live with the possibility for efficiency sake”. And the review team accepts the reasoning. This exception is valid. And the code inspection process should manage and document this collaborative decision within overall code quality reports.
5. Document Traceability
Traceability is important for audits.
To have traceability, you need to capture the history of software quality. This includes inspection results from automated analysis, collaborative decisions, deviations, and trend analysis. Having the right code inspection tools makes this easy.
What to Look For in Code Inspection Tools
The best way to achieve quality in embedded systems is with the right code inspection tools.
A good code inspection tool should include:
- Automated inspection
- Collaboration system
- Analysis metrics
Helix QAC includes all of these capabilities and makes it easy to continuously inspect C and C++ code.
Sign up for our next live demo to see how.