Each compiler could report after the build many warnings. These warnings won’t keep your code from compiling except if you decide to treat them as errors. Don’t hesitate to take a look as these warnings instead of ignoring them. Indeed compiler warnings are often indicators of future bugs that you would see only at runtime.
Clang is a C/C++/Objective C compiler with many interesting features, here are some major end user features:
- Fast compiles and low memory usage.
- Expressive diagnostics.
- GCC compatibility.
In this post we will focus on the Expressive diagnostics feature. and how we can get these diagnostics for Visual C++ projects.
The clang team aims to provide as clear and expressive error messages as possible. They try to make it as user friendly as they can for a command line compiler. To do so, clang should pinpoint exactly what is wrong in the code. This is done through a diagnostics engine which processes the error information into a user friendly message.
To discover the Clang diagnostics benefits, let’s compile a minimal C++ source code with both Visual C++ and Clang, and compare between the warnings reported. All warnings will be enabled for the two compilers.
The Microsoft c++ compiler report the following warning
- warning C4100: ‘n’ : unreferenced formal parameter
Clang report three warnings:
- no previous prototype for function ‘Print’
- use of old-style cast
- unused parameter ‘n’
What’s interesting with Clang is that it reports also diagnostics related to coding best practices, for example the warning “no previous prototype for function Print” is reported because Print is not declared as static function so it could be used in another source file, and in this case it’s recommended that the declaration exist in an include file.
And to have more concrete idea about the Clang diagnostics, let’s compile a C++ open source project with both Clang and Microsoft compiler to discover what kind of warnings are reported by them.
We take as example the “7 zip” project and compile only the module Gui.vcproj. we will focus only on warnings related to the project source code and not the external include files.
The Microsoft compiler report these kinds of warnings
- Bytes padding added after data member.
- Conversion issues.
- Function not inlined.
- Class has virtual functions, but destructor is not virtual.
- Catch(…) semantics changed since Visual C++ 7.1; structured exceptions (SEH) are no longer caught.
- Cast issues.
- Enumerator ‘kInfo’ in switch of enum ‘NCommandType::EEnum’ is not explicitly handled by a case label.
- ‘GetVersionExA’: was declared deprecated.
The Clang compiler report these kind of warnings:
- Use of old-style cast
- Missing field ‘MinLen’ initializer
- Macro is not used
- Declaration requires a global constructor
- Declaration requires an exit-time destructor
- Conversion issues
- Cast issues
- enumeration values ‘kWithoutPrompt’, ‘kAutoRename’, and ‘kAutoRenameExisting’ not handled in switch
- Operand of ? changes signedness: ‘const int’ to ‘unsigned int’
- Declaration shadows a local variable
- ISO C++11 does not allow conversion from string literal to ‘LPSTR’ (aka ‘char *’)
- No previous prototype for function
- Comparison issues
- ‘GetVersionExA’: was declared deprecated
- dynamic exception specifications are deprecated
- ‘&&’ within ‘||’
- ‘CBenchRandomGenerator’ has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit
- Delete called on ‘CBenchmarkInStream’ that has virtual functions but non-virtual destructor
- ‘CBenchmarkInStream’ has virtual functions but non-virtual destructor
- Equality comparison result unused
- Explicitly assigning value of variable of type ‘INT_PTR’ (aka ‘int’) to itself
- Add explicit braces to avoid dangling else
As we can observe Clang reports more interesting warnings than the Microsoft compiler, some of them are generally reported by static analysis tools, and it’s recommended to take seriously these warnings, they could reveal many bugs.
How to get the Clang diagnostics for your Visual C++ projects?
The Clang diagnostics helps the developers to improve their C/C++ souce code quality, and it will be useful if we can get them for our Visual C++ projects.
The first alternative is to compile your projects using Clang, here’s an msdn post to show you how to use Clang as compiler in VS.
The following query give us all the Clang diagnostics:
The Gui project from 7-Zip application has only 10k line of code and 1186 diagnostics, for medium and big projects you could have thousands of diagnostics, and in this case it will be useful to filter them, and get only some kind of warnings.
For example we can modify the previous query and get only warnings related to deprecated usage.
Warnings are often indicators of future bugs, it’s recommended to not ignore them. And Clang reports many interesting diagnostics, some of them are related to coding best practices, and removing these warnings will contribute to improve the quality of you project source code.