You can check to see if you are breaking the rules of the C++ Core Guidelines.
Let’s start with a program that breaks type safety, bounds safety, and lifetime safety.
1 // gslCheck.cpp 2 3 #include <iostream> 4 5 void f(int* p, int count) { 6 } 7 8 void f2(int* p) { 9 int x = *p; 10 } 11 12 int main() { 13 14 // Break of type safety 15 // use of a c-cast 16 double d = 2; 17 auto p = (long*)&d; 18 auto q = (long long*)&d; 19 20 // Break of bounds safety 21 // array-to-pointer decay 22 int myArray[100]; 23 f(myArray, 100); 24 25 // Break of lifetime safety 26 // a is not valid 27 int* a = new int; 28 delete a; 29 f2(a); 30 31 }
The comments in the source code document the issues. Let me check the program with Visual Studio and clang-tidy.
These are the steps to detect the issues with the program gslCheck.cpp
.
Enable code analysis on build.
You have to enable the checkbox. Per default, type-safety, bounds-safety, and lifetime-safety rules are not part of the Microsoft Native Recommended Rules. See Figure A.1.
Figure A.1 Enable code analysis
Configure the active rules.
As you can see in Figure A.2, I create rule set CheckProfiles, which consists of the rules C++ Core Guidelines Bounds Rules, C++ Core Guidelines Type Rules, and C++ Core Guidelines Lifetime Rules.
Figure A.2 Configure the applied rules
Run code analysis.
Applying the set of rules on the code example is quite promising. See Figure A.3.
Figure A.3 Automatic managing of a device
All issues are found. For each issue such as the first one, I get the line number (17) and the rule of the affected profile (Type.4).
Suppress warnings.
Sometimes you want to suppress specific warnings. You can achieve this with attributes. My next example, gslCheckSuppress.cpp
, applies an array-to-pointer decay twice. Only the second call should give a warning.
// gslCheckSuppress.cpp; C++20 with MSVC #include <iostream> void f(int* p, int count) { } int main() { int myArray[100]; // Break of bounds safety [[gsl::suppress(bounds.3)]] { // suppress warning f(myArray, 100); } f(myArray, 100); // warning }
The attribute gsl::suppress(bounds.3)
behaves as expected. It’s only valid in its scope. The second violation of bounds safety is displayed. See Figure A.4.
Figure A.4 Suppress warnings
clang-tidy is a clang-based C++ “linter” tool. Its purpose is to provide an extensible framework for diagnosing and fixing typical programming errors, like style violations, interface misuse, or bugs that can be deduced via static analysis. clang-tidy is modular and provides a convenient interface for writing new checks—Extra Clang Tools 11 documentation (https://clang.llvm.org/extra/clang-tidy/).
clang-tidy supports more than 200 rules. About twenty of them are dedicated to the C++ Core Guidelines. Here are the steps to detect the issues with the program gslCheck.cpp
.
Apply the C++ Core Guidelines checks.
The command line
clang-tidy -checks=-*,cppcoreguidelines-*gslCheck.cpp
checks the C++ Core Guidelines exclusively (see Figure A.5). The option -checks
expects comma-separated values of glob patterns and means the following in this case:
Figure A.5 Check the C++ Core Guidelines exclusively
-*
: Disable the default checks of clang-tidy.
cppcoreguidelines-*
: Enable the C++ Core Guidelines checks.
These checks detected only the type-safety issues in the program gslCheck.cpp
.
Apply the clang-tidy checks and the C++ Core Guidelines checks.
The slightly simplified command line
clang-tidy -checks=cppcoreguidelines-*gslCheck.cpp
also applies the clang-tidy checks (see Figure A.6). Now, the lifetime-safety issue is detected.
Figure A.6 Check the C++ Core Guidelines with clang-tidy
In contrast to Visual Studio, I could not detect the boundary-safety issue with clang-tidy.