In the previous lesson, we introduced programs such as clang-format, which can analyze and update our code to match a layout style we can configure.
There is a diverse ecosystem of tooling and plugins that can take this analysis much further.
Static analysis programs read our code, warn us of any potential issues, and make suggestions on how we can improve it. This can include things like:
camelCase
for function names or appending m
to class members.#include
directives that are not necessary, functions we defined but never called, and variables we declared but never usedconst
Tools like these can be a huge benefit, and this is particularly true when we’re in the earlier stages of our learning journey.
One of the main ways new developers learn is through a "code review" process within their teams, where more experienced developers read through their code to detect potential issues or make suggestions.
This is generally not available to developers who are just learning on their own. But, static analysis tools are getting better all the time, and are quickly becoming an increasingly worthy substitute.
Our editors typically have some functionality to this effect built-in. We can also use plugins or standalone programs, which often have more robust features
Many editors offer code analysis tools as standard. This includes Visual Studio.
In Visual Studio projects, static analysis can be configured under Analyze in the top menu bar. Once set up, we can then see suggestions within our source files on how we might want to modify them.
Usually, these suggestions have a green underline. Below, we see Visual Studio asking us to consider marking a variable as const
:
ReSharper is a powerful and popular tool for static analysis. It is not free but does have a free trial, as well as a free license if you are in education. You can find out more on their site: ReSharper C++
It comes with a Visual Studio plugin that provides inline highlighting within our source code, similar to Visual Studio's native feature. It also has a UI where we can configure the checks we care about.
Below, we see ReSharper detecting several issues with a basic header file.
This file is perfectly fine from a compiler's perspective, but static analysis shows it has missing header guards, unnecessary syntax, uninitialized variables, and more:
CppCheck is a free, cross-platform tool that provides code analysis of our C++ projects. It comes bundled with a graphical interface, which we can load our project into, and get a range of code suggestions.
Below, we see CppCheck has found some functions in our code that are never being used:
Compilers can often also detect problems with our code, but those problems may not necessarily prevent our code from being compilable.
When this happens, the compiler will build our software as usual, but additionally emit warnings for the potential issues it found.
The following program will compile successfully, but the compiler will generate a warning as our function is returning a pointer to a local variable.
A function’s local variables are deallocated when the function ends, meaning our return value will be a dangling pointer:
int* GetNumber() {
int MyNumber{42};
return &MyNumber;
}
int main() {}
warning: returning address of local variable or temporary: MyNumber
We should keep an eye out for these warnings, and fix them as needed. Our IDEs typically have a UI that presents compiler warnings. In Visual Studio, this is available under View > Error List
This lesson explores static analysis, and how it can improve code quality by identifying potential issues, suggesting enhancements, and ensuring adherence to coding standards.
We delved into various tools, including Visual Studio’s built-in code analysis, ReSharper, and CppCheck, to understand how they aid in this process.
Finally, we covered compiler warnings, which complement static analysis by highlighting problems that do not prevent compilation but may lead to runtime errors.
In our next lesson, we'll delve into the world of attributes in C++, focusing on [[likely]]
, [[nodiscard]]
, and [[deprecated]]
.
These attributes offer a way to provide more information to the compiler about your code, enabling it to optimize better and warn about potential issues. We’ll cover:
[[nodiscard]]
Attribute: Learn how this attribute prompts warnings when the return values of functions are ignored, helping to catch bugs.[[likely]]
and [[unlikely]]
Attributes: Understanding how these attributes provide hints to the compiler about the expected branch probability, which can optimize performance.[[deprecated]]
Attribute: Discover how to indicate that a feature is obsolete and should no longer be used, which is crucial for maintaining projects in collaborative environments.An introduction to static analysis tools, and how they can help beginners learn faster and improve code quality
Become a software engineer with C++. Starting from the basics, we guide you step by step along the way