.\" Man page generated from reStructuredText. . . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .TH "EXTRACLANGTOOLS" "1" "Mar 02, 2024" "17" "Extra Clang Tools" .SH NAME extraclangtools \- Extra Clang Tools Documentation .sp Welcome to the clang\-tools\-extra project which contains extra tools built using Clang\(aqs tooling APIs. .SH EXTRA CLANG TOOLS 17.0.6 RELEASE NOTES .INDENT 0.0 .IP \(bu 2 \fI\%Introduction\fP .IP \(bu 2 \fI\%What\(aqs New in Extra Clang Tools 17.0.6?\fP .INDENT 2.0 .IP \(bu 2 \fI\%Major New Features\fP .IP \(bu 2 \fI\%Improvements to clangd\fP .INDENT 2.0 .IP \(bu 2 \fI\%Inlay hints\fP .IP \(bu 2 \fI\%Diagnostics\fP .IP \(bu 2 \fI\%Semantic Highlighting\fP .IP \(bu 2 \fI\%Compile flags\fP .IP \(bu 2 \fI\%Hover\fP .IP \(bu 2 \fI\%Code completion\fP .IP \(bu 2 \fI\%Signature help\fP .IP \(bu 2 \fI\%Cross\-references\fP .IP \(bu 2 \fI\%Objective\-C\fP .IP \(bu 2 \fI\%Miscellaneous\fP .UNINDENT .IP \(bu 2 \fI\%Improvements to clang\-doc\fP .IP \(bu 2 \fI\%Improvements to clang\-query\fP .IP \(bu 2 \fI\%Improvements to clang\-rename\fP .IP \(bu 2 \fI\%Improvements to clang\-tidy\fP .INDENT 2.0 .IP \(bu 2 \fI\%New checks\fP .IP \(bu 2 \fI\%New check aliases\fP .IP \(bu 2 \fI\%Changes in existing checks\fP .IP \(bu 2 \fI\%Removed checks\fP .UNINDENT .IP \(bu 2 \fI\%Improvements to include\-fixer\fP .IP \(bu 2 \fI\%Improvements to clang\-include\-fixer\fP .IP \(bu 2 \fI\%Improvements to modularize\fP .IP \(bu 2 \fI\%Improvements to pp\-trace\fP .IP \(bu 2 \fI\%Clang\-tidy Visual Studio plugin\fP .UNINDENT .UNINDENT .sp Written by the \fI\%LLVM Team\fP .SS Introduction .sp This document contains the release notes for the Extra Clang Tools, part of the Clang release 17.0.6\&. Here we describe the status of the Extra Clang Tools in some detail, including major improvements from the previous release and new feature work. All LLVM releases may be downloaded from the \fI\%LLVM releases web site\fP\&. .sp For more information about Clang or LLVM, including information about the latest release, please see the \fI\%Clang Web Site\fP or the \fI\%LLVM Web Site\fP\&. .sp Note that if you are reading this file from a Git checkout or the main Clang web page, this document applies to the \fInext\fP release, not the current one. To see the release notes for a specific release, please see the \fI\%releases page\fP\&. .SS What\(aqs New in Extra Clang Tools 17.0.6? .sp Some of the major new features and improvements to Extra Clang Tools are listed here. Generic improvements to Extra Clang Tools as a whole or to its underlying infrastructure are described first, followed by tool\-specific sections. .SS Major New Features .sp \&... .SS Improvements to clangd .SS Inlay hints .SS Diagnostics .SS Semantic Highlighting .SS Compile flags .SS Hover .SS Code completion .SS Signature help .SS Cross\-references .SS Objective\-C .SS Miscellaneous .SS Improvements to clang\-doc .SS Improvements to clang\-query .sp The improvements are... .SS Improvements to clang\-rename .sp The improvements are... .SS Improvements to clang\-tidy .INDENT 0.0 .IP \(bu 2 New global configuration file options \fIHeaderFileExtensions\fP and \fIImplementationFileExtensions\fP, replacing the check\-local options of the same name. .IP \(bu 2 Support specifying \fIChecks\fP as a YAML list in the \fI\&.clang\-tidy\fP configuration file. .IP \(bu 2 Fix a potential crash when using the \fI\-\-dump\-config\fP option. .IP \(bu 2 Support specifying \fISystemHeaders\fP in the \fI\&.clang\-tidy\fP configuration file, with the same functionality as the command\-line option \fI\-\-system\-headers\fP\&. .IP \(bu 2 \fIWarningsAsErrors\fP (\fI\-\-warnings\-as\-errors=\fP) no longer promotes unlisted warnings to errors. Only the warnings listed in \fIChecks\fP (\fI\-\-checks=\fP) will be promoted to errors. For custom error promotion, use \fI\-Werror=\fP on the compiler command\-line, irrespective of \fIChecks\fP (\fI\-\-checks=\fP) settings. .IP \(bu 2 Fixed an issue where compiler warnings couldn\(aqt be suppressed using \fI\-Wno\-\fP under C++20 and above. .UNINDENT .SS New checks .INDENT 0.0 .IP \(bu 2 New \fI\%bugprone\-empty\-catch\fP check. .sp Detects and suggests addressing issues with empty catch statements. .IP \(bu 2 New \fI\%bugprone\-multiple\-new\-in\-one\-expression\fP check. .sp Finds multiple \fBnew\fP operator calls in a single expression, where the allocated memory by the first \fBnew\fP may leak if the second allocation fails and throws exception. .IP \(bu 2 New \fI\%bugprone\-non\-zero\-enum\-to\-bool\-conversion\fP check. .sp Detect implicit and explicit casts of \fBenum\fP type into \fBbool\fP where \fBenum\fP type doesn\(aqt have a zero\-value enumerator. .IP \(bu 2 New \fI\%bugprone\-switch\-missing\-default\-case\fP check. .sp Ensures that switch statements without default cases are flagged, focuses only on covering cases with non\-enums where the compiler may not issue warnings. .IP \(bu 2 New \fI\%bugprone\-unique\-ptr\-array\-mismatch\fP check. .sp Finds initializations of C++ unique pointers to non\-array type that are initialized with an array. .IP \(bu 2 New \fI\%bugprone\-unsafe\-functions\fP check. .sp Checks for functions that have safer, more secure replacements available, or are considered deprecated due to design flaws. This check relies heavily on, but is not exclusive to, the functions from the \fIAnnex K. \(dqBounds\-checking interfaces\(dq\fP of C11. .IP \(bu 2 New \fI\%cppcoreguidelines\-avoid\-capturing\-lambda\-coroutines\fP check. .sp Flags C++20 coroutine lambdas with non\-empty capture lists that may cause use\-after\-free errors and suggests avoiding captures or ensuring the lambda closure object has a guaranteed lifetime. .IP \(bu 2 New \fI\%cppcoreguidelines\-misleading\-capture\-default\-by\-value\fP check. .sp Warns when lambda specify a by\-value capture default and capture \fBthis\fP\&. .IP \(bu 2 New \fI\%cppcoreguidelines\-missing\-std\-forward\fP check. .sp Warns when a forwarding reference parameter is not forwarded within the function body. .IP \(bu 2 New \fI\%cppcoreguidelines\-rvalue\-reference\-param\-not\-moved\fP check. .sp Warns when an rvalue reference function parameter is never moved within the function body. .IP \(bu 2 New \fI\%llvmlibc\-inline\-function\-decl\fP check. .sp Checks that all implicit and explicit inline functions in header files are tagged with the \fBLIBC_INLINE\fP macro. .IP \(bu 2 New \fI\%misc\-header\-include\-cycle\fP check. .sp Check detects cyclic \fB#include\fP dependencies between user\-defined headers. .IP \(bu 2 New \fI\%misc\-include\-cleaner\fP check. .sp Checks for unused and missing includes. .IP \(bu 2 New \fI\%modernize\-type\-traits\fP check. .sp Converts standard library type traits of the form \fBtraits<...>::type\fP and \fBtraits<...>::value\fP into \fBtraits_t<...>\fP and \fBtraits_v<...>\fP respectively. .IP \(bu 2 New \fI\%modernize\-use\-std\-print\fP check. .sp Converts calls to \fBprintf\fP, \fBfprintf\fP, \fBabsl::PrintF\fP, \fBabsl::FPrintf\fP or other functions via configuration options, to equivalent calls to C++23\(aqs \fBstd::print\fP and \fBstd::println\fP, or other functions via a configuration option, modifying the format string appropriately and removing now\-unnecessary calls to \fBstd::string::c_str()\fP and \fBstd::string::data()\fP\&. .IP \(bu 2 New \fI\%performance\-avoid\-endl\fP check. .sp Finds uses of \fBstd::endl\fP on streams and replaces them with \fB\(aq\en\(aq\fP\&. .IP \(bu 2 New \fI\%performance\-noexcept\-destructor\fP check. .sp Finds user declared destructors which are not \fBnoexcept\fP\&. .IP \(bu 2 New \fI\%performance\-noexcept\-swap\fP check. .sp Finds user declared swap functions which are not \fBnoexcept\fP\&. .IP \(bu 2 New \fI\%readability\-avoid\-unconditional\-preprocessor\-if\fP check. .sp Finds code blocks that are constantly enabled or disabled in preprocessor directives by analyzing \fB#if\fP conditions, such as \fB#if 0\fP and \fB#if 1\fP, etc. .IP \(bu 2 New \fI\%readability\-operators\-representation\fP check. .sp Enforces consistent token representation for invoked binary, unary and overloaded operators in C++ code. .UNINDENT .SS New check aliases .INDENT 0.0 .IP \(bu 2 New alias \fI\%cert\-msc24\-c\fP to \fI\%bugprone\-unsafe\-functions\fP was added. .IP \(bu 2 New alias \fI\%cert\-msc33\-c\fP to \fI\%bugprone\-unsafe\-functions\fP was added. .IP \(bu 2 New alias \fI\%cppcoreguidelines\-noexcept\-destructor\fP to \fI\%performance\-noexcept\-destructor\fP was added. .IP \(bu 2 New alias \fI\%cppcoreguidelines\-noexcept\-move\-operations\fP to \fI\%performance\-noexcept\-move\-constructor\fP was added. .IP \(bu 2 New alias \fI\%cppcoreguidelines\-noexcept\-swap\fP to \fI\%performance\-noexcept\-swap\fP was added. .IP \(bu 2 New alias \fI\%cppcoreguidelines\-use\-default\-member\-init\fP to \fI\%modernize\-use\-default\-member\-init\fP was added. .UNINDENT .SS Changes in existing checks .INDENT 0.0 .IP \(bu 2 Fixed false\-positives in \fI\%bugprone\-branch\-clone\fP check by ignoring auto\-generated code, template instances, implicit code patterns and duplicated switch cases marked with the \fB[[fallthrough]]\fP attribute. .IP \(bu 2 Improved \fI\%bugprone\-dangling\-handle\fP check enhancing detection of handles behind type aliases. .IP \(bu 2 Deprecated check\-local options \fIHeaderFileExtensions\fP in \fI\%bugprone\-dynamic\-static\-initializers\fP check. Global options of the same name should be used instead. .IP \(bu 2 Improved \fI\%bugprone\-exception\-escape\fP check to not emit warnings for forward declarations of functions, explicitly declared throwing functions, coroutines throwing exceptions in their bodies and skip \fBnoexcept\fP functions during call stack analysis. .IP \(bu 2 Improved \fI\%bugprone\-fold\-init\-type\fP to handle iterators that do not define \fIvalue_type\fP type aliases. .IP \(bu 2 Improved \fI\%bugprone\-forwarding\-reference\-overload\fP check to ignore constructors with associated constraints (C++ concepts). .IP \(bu 2 Improved \fI\%bugprone\-incorrect\-roundings\fP check by adding support for other floating point representations in float constant like \fB0.5L\fP\&. .IP \(bu 2 Improved the performance of the \fI\%bugprone\-reserved\-identifier\fP check through optimizations. .IP \(bu 2 Improved the \fI\%bugprone\-reserved\-identifier\fP check by enhancing the \fIAllowedIdentifiers\fP option to support regular expressions. .IP \(bu 2 Deprecated check\-local options \fIHeaderFileExtensions\fP and \fIImplementationFileExtensions\fP in \fI\%bugprone\-suspicious\-include\fP check. Global options of the same name should be used instead. .IP \(bu 2 Improved \fI\%bugprone\-too\-small\-loop\-variable\fP check. Basic support for bit\-field and integer members as a loop variable or upper limit were added. .IP \(bu 2 Improved \fI\%bugprone\-unchecked\-optional\-access\fP check to properly handle calls to \fBstd::forward\fP and support for \fBfolly::Optional\fP were added. .IP \(bu 2 Extend \fI\%bugprone\-unused\-return\-value\fP check to check for all functions with specified return types using the \fBCheckedReturnTypes\fP option. .IP \(bu 2 Improved \fI\%bugprone\-use\-after\-move\fP check. Detect uses and moves in constructor initializers. Correctly handle constructor arguments as being sequenced when constructor call is written as list\-initialization. Understand that there is a sequence point between designated initializers. .IP \(bu 2 Improved \fI\%bugprone\-swapped\-arguments\fP by enhancing handling of implicit conversions, resulting in better detection of argument swaps involving integral and floating\-point types. .IP \(bu 2 Deprecated \fI\%cert\-dcl21\-cpp\fP check. .IP \(bu 2 Fixed \fI\%cppcoreguidelines\-avoid\-const\-or\-ref\-data\-members\fP check to emit warnings only on classes that are copyable/movable, as required by the corresponding rule. .IP \(bu 2 Improved \fI\%cppcoreguidelines\-owning\-memory\fP check now finds more issues, especially those related to implicit casts. .IP \(bu 2 Deprecated C.48 enforcement from \fI\%cppcoreguidelines\-prefer\-member\-initializer\fP\&. Please use \fI\%cppcoreguidelines\-use\-default\-member\-init\fP instead. .IP \(bu 2 Improved \fI\%cppcoreguidelines\-pro\-bounds\-constant\-array\-index\fP check to cover type aliases of \fBstd::array\fP\&. .IP \(bu 2 Fixed a false positive in \fI\%cppcoreguidelines\-slicing\fP check when warning would be emitted in constructor for virtual base class initialization. .IP \(bu 2 Deprecated check\-local options \fIHeaderFileExtensions\fP in \fI\%google\-build\-namespaces\fP check. Global options of the same name should be used instead. .IP \(bu 2 Deprecated check\-local options \fIHeaderFileExtensions\fP in \fI\%google\-global\-names\-in\-headers\fP check. Global options of the same name should be used instead. .IP \(bu 2 Fixed an issue in \fI\%google\-readability\-avoid\-underscore\-in\-googletest\-name\fP when using \fBDISABLED_\fP in the test suite name. .IP \(bu 2 Deprecated check\-local options \fIHeaderFileExtensions\fP in \fI\%llvm\-header\-guard\fP check. Global options of the same name should be used instead. .IP \(bu 2 Fix false positive in \fI\%llvmlibc\-inline\-function\-decl\fP when using templated function with separate declarations and definitions. .IP \(bu 2 Improved the performance of the \fI\%misc\-confusable\-identifiers\fP check through optimizations. .IP \(bu 2 Deprecated check\-local options \fIHeaderFileExtensions\fP in \fI\%misc\-definitions\-in\-headers\fP check. Global options of the same name should be used instead. .IP \(bu 2 Fixed false positive in \fI\%misc\-definitions\-in\-headers\fP to avoid warning on declarations inside anonymous namespaces. .IP \(bu 2 Fixed false\-positive in \fI\%misc\-redundant\-expression\fP check where expressions like \fBalignof\fP or \fBsizeof\fP were incorrectly flagged as identical. .IP \(bu 2 Improved \fI\%misc\-unused\-parameters\fP check with new \fIIgnoreVirtual\fP option to optionally ignore virtual methods. .IP \(bu 2 Deprecated check\-local options \fIHeaderFileExtensions\fP in \fI\%misc\-unused\-using\-decls\fP check. Global options of the same name should be used instead. .IP \(bu 2 Improved \fI\%modernize\-concat\-nested\-namespaces\fP to fix incorrect fixes when using macro between namespace declarations, to fix false positive when using namespace with attributes and to support nested inline namespace introduced in c++20. .IP \(bu 2 Fixed an issue in \fI\%modernize\-loop\-convert\fP generating wrong code when using structured bindings. .IP \(bu 2 In \fI\%modernize\-use\-default\-member\-init\fP check, template constructors are now counted towards hand\-written constructors and skipped if more than one exists. Additionally, a crash that occurred with array members being value\-initialized has been fixed. .IP \(bu 2 Fixed false positive in \fI\%modernize\-use\-equals\-default\fP check for special member functions containing macros or preprocessor directives, and out\-of\-line special member functions in unions. .IP \(bu 2 Improved \fI\%modernize\-use\-override\fP check with new \fIIgnoreTemplateInstantiations\fP option to optionally ignore virtual function overrides that are part of template instantiations. .IP \(bu 2 Improved \fI\%performance\-for\-range\-copy\fP check by extending const usage analysis to include the type\(aqs members. .IP \(bu 2 Improved \fI\%performance\-inefficient\-vector\-operation\fP check by extending const usage analysis to include the type\(aqs members. .IP \(bu 2 Improved \fI\%performance\-move\-const\-arg\fP check to warn when move special member functions are not available. .IP \(bu 2 Improved \fI\%performance\-no\-automatic\-move\fP check to warn on \fBconst &&\fP constructors and ignore \fBconst\fP local variable to which NRVO is applied. .IP \(bu 2 Fixed an issue in the \fI\%performance\-noexcept\-move\-constructor\fP checker that was causing false\-positives when the move constructor or move assign operator were defaulted. .IP \(bu 2 Improved \fI\%performance\-unnecessary\-copy\-initialization\fP check by extending const usage analysis to include the type\(aqs members. .IP \(bu 2 Improved \fI\%performance\-unnecessary\-value\-param\fP check by extending const usage analysis to include the type\(aqs members. .IP \(bu 2 Improved \fI\%readability\-container\-data\-pointer\fP check with new \fIIgnoredContainers\fP option to ignore some containers. .IP \(bu 2 Fixed a false positive in \fI\%readability\-container\-size\-empty\fP check when comparing \fBstd::array\fP objects to default constructed ones. The behavior for this and other relevant classes can now be configured with a new option. .IP \(bu 2 Fixed a false negative in \fI\%readability\-convert\-member\-functions\-to\-static\fP when a nested class in a member function uses a \fBthis\fP pointer. .IP \(bu 2 Fixed reading \fIHungarianNotation.CString.*\fP options in \fI\%readability\-identifier\-naming\fP check. .IP \(bu 2 Renamed \fIHungarianNotation.CString\fP options \fICharPrinter\fP and \fIWideCharPrinter\fP to \fICharPointer\fP and \fIWideCharPointer\fP respectively in \fI\%readability\-identifier\-naming\fP check. .IP \(bu 2 Updated the Hungarian prefixes for enums in C files to match those used in C++ files for improved readability, as checked by \fI\%readability\-identifier\-naming\fP\&. To preserve the previous behavior of using \fIi\fP as the prefix for enum tags, set the \fIEnumConstantPrefix\fP option to \fIi\fP instead of using \fIEnumConstantHungarianPrefix\fP\&. .IP \(bu 2 Fixed a hungarian notation issue in \fI\%readability\-identifier\-naming\fP which failed to indicate the number of asterisks. .IP \(bu 2 Fixed an issue in \fI\%readability\-identifier\-naming\fP when specifying an empty string for \fIPrefix\fP or \fISuffix\fP options could result in the style not being used. .IP \(bu 2 Improved the performance of the \fI\%readability\-identifier\-naming\fP check through optimizations. .IP \(bu 2 Fixed a false positive in \fI\%readability\-implicit\-bool\-conversion\fP check warning would be unnecessarily emitted for explicit cast using direct list initialization. .IP \(bu 2 Added support to optionally ignore user\-defined literals in \fI\%readability\-magic\-numbers\fP check and improved it to allow magic numbers in type aliases such as \fBusing\fP and \fBtypedef\fP declarations if the new \fIIgnoreTypeAliases\fP option is set to \fItrue\fP\&. .IP \(bu 2 Fixed a false positive in \fI\%readability\-misleading\-indentation\fP check when warning would be unnecessarily emitted for template dependent \fBif constexpr\fP\&. .IP \(bu 2 Fixed a false positive in \fI\%readability\-named\-parameter\fP for defaulted out\-of\-line special member functions. .IP \(bu 2 Fixed incorrect fixes in \fI\%readability\-redundant\-declaration\fP check when linkage (like \fBextern \(dqC\(dq\fP) is explicitly specified. .IP \(bu 2 Improved \fI\%readability\-redundant\-string\-cstr\fP check to recognise unnecessary \fBstd::string::c_str()\fP and \fBstd::string::data()\fP calls in arguments to \fBstd::print\fP, \fBstd::format\fP or other functions listed in the \fIStringParameterFunction\fP check option. .IP \(bu 2 Improved \fI\%readability\-static\-accessed\-through\-instance\fP check to support unscoped enumerations through instances and fixed usage of anonymous structs or classes. .UNINDENT .SS Removed checks .SS Improvements to include\-fixer .sp The improvements are... .SS Improvements to clang\-include\-fixer .sp The improvements are... .SS Improvements to modularize .sp The improvements are... .SS Improvements to pp\-trace .SS Clang\-tidy Visual Studio plugin .SH CLANG-TIDY .SS Contents .INDENT 0.0 .IP \(bu 2 \fI\%Clang\-Tidy\fP .INDENT 2.0 .IP \(bu 2 \fI\%Using clang\-tidy\fP .IP \(bu 2 \fI\%Suppressing Undesired Diagnostics\fP .UNINDENT .UNINDENT .sp See also: .SS Clang\-Tidy Checks .SS abseil\-cleanup\-ctad .sp Suggests switching the initialization pattern of \fBabsl::Cleanup\fP instances from the factory function to class template argument deduction (CTAD), in C++17 and higher. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C auto c1 = absl::MakeCleanup([] {}); const auto c2 = absl::MakeCleanup(std::function([] {})); .ft P .fi .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C absl::Cleanup c1 = [] {}; const absl::Cleanup c2 = std::function([] {}); .ft P .fi .UNINDENT .UNINDENT .SS abseil\-duration\-addition .sp Check for cases where addition should be performed in the \fBabsl::Time\fP domain. When adding two values, and one is known to be an \fBabsl::Time\fP, we can infer that the other should be interpreted as an \fBabsl::Duration\fP of a similar scale, and make that inference explicit. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Original \- Addition in the integer domain int x; absl::Time t; int result = absl::ToUnixSeconds(t) + x; // Suggestion \- Addition in the absl::Time domain int result = absl::ToUnixSeconds(t + absl::Seconds(x)); .ft P .fi .UNINDENT .UNINDENT .SS abseil\-duration\-comparison .sp Checks for comparisons which should be in the \fBabsl::Duration\fP domain instead of the floating point or integer domains. .sp N.B.: In cases where a \fBDuration\fP was being converted to an integer and then compared against a floating\-point value, truncation during the \fBDuration\fP conversion might yield a different result. In practice this is very rare, and still indicates a bug which should be fixed. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Original \- Comparison in the floating point domain double x; absl::Duration d; if (x < absl::ToDoubleSeconds(d)) ... // Suggested \- Compare in the absl::Duration domain instead if (absl::Seconds(x) < d) ... // Original \- Comparison in the integer domain int x; absl::Duration d; if (x < absl::ToInt64Microseconds(d)) ... // Suggested \- Compare in the absl::Duration domain instead if (absl::Microseconds(x) < d) ... .ft P .fi .UNINDENT .UNINDENT .SS abseil\-duration\-conversion\-cast .sp Checks for casts of \fBabsl::Duration\fP conversion functions, and recommends the right conversion function instead. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Original \- Cast from a double to an integer absl::Duration d; int i = static_cast(absl::ToDoubleSeconds(d)); // Suggested \- Use the integer conversion function directly. int i = absl::ToInt64Seconds(d); // Original \- Cast from a double to an integer absl::Duration d; double x = static_cast(absl::ToInt64Seconds(d)); // Suggested \- Use the integer conversion function directly. double x = absl::ToDoubleSeconds(d); .ft P .fi .UNINDENT .UNINDENT .sp Note: In the second example, the suggested fix could yield a different result, as the conversion to integer could truncate. In practice, this is very rare, and you should use \fBabsl::Trunc\fP to perform this operation explicitly instead. .SS abseil\-duration\-division .sp \fBabsl::Duration\fP arithmetic works like it does with integers. That means that division of two \fBabsl::Duration\fP objects returns an \fBint64\fP with any fractional component truncated toward 0. See \fI\%this link\fP for more information on arithmetic with \fBabsl::Duration\fP\&. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C absl::Duration d = absl::Seconds(3.5); int64 sec1 = d / absl::Seconds(1); // Truncates toward 0. int64 sec2 = absl::ToInt64Seconds(d); // Equivalent to division. assert(sec1 == 3 && sec2 == 3); double dsec = d / absl::Seconds(1); // WRONG: Still truncates toward 0. assert(dsec == 3.0); .ft P .fi .UNINDENT .UNINDENT .sp If you want floating\-point division, you should use either the \fBabsl::FDivDuration()\fP function, or one of the unit conversion functions such as \fBabsl::ToDoubleSeconds()\fP\&. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C absl::Duration d = absl::Seconds(3.5); double dsec1 = absl::FDivDuration(d, absl::Seconds(1)); // GOOD: No truncation. double dsec2 = absl::ToDoubleSeconds(d); // GOOD: No truncation. assert(dsec1 == 3.5 && dsec2 == 3.5); .ft P .fi .UNINDENT .UNINDENT .sp This check looks for uses of \fBabsl::Duration\fP division that is done in a floating\-point context, and recommends the use of a function that returns a floating\-point value. .SS abseil\-duration\-factory\-float .sp Checks for cases where the floating\-point overloads of various \fBabsl::Duration\fP factory functions are called when the more\-efficient integer versions could be used instead. .sp This check will not suggest fixes for literals which contain fractional floating point values or non\-literals. It will suggest removing superfluous casts. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Original \- Providing a floating\-point literal. absl::Duration d = absl::Seconds(10.0); // Suggested \- Use an integer instead. absl::Duration d = absl::Seconds(10); // Original \- Explicitly casting to a floating\-point type. absl::Duration d = absl::Seconds(static_cast(10)); // Suggested \- Remove the explicit cast absl::Duration d = absl::Seconds(10); .ft P .fi .UNINDENT .UNINDENT .SS abseil\-duration\-factory\-scale .sp Checks for cases where arguments to \fBabsl::Duration\fP factory functions are scaled internally and could be changed to a different factory function. This check also looks for arguments with a zero value and suggests using \fBabsl::ZeroDuration()\fP instead. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Original \- Internal multiplication. int x; absl::Duration d = absl::Seconds(60 * x); // Suggested \- Use absl::Minutes instead. absl::Duration d = absl::Minutes(x); // Original \- Internal division. int y; absl::Duration d = absl::Milliseconds(y / 1000.); // Suggested \- Use absl:::Seconds instead. absl::Duration d = absl::Seconds(y); // Original \- Zero\-value argument. absl::Duration d = absl::Hours(0); // Suggested = Use absl::ZeroDuration instead absl::Duration d = absl::ZeroDuration(); .ft P .fi .UNINDENT .UNINDENT .SS abseil\-duration\-subtraction .sp Checks for cases where subtraction should be performed in the \fBabsl::Duration\fP domain. When subtracting two values, and the first one is known to be a conversion from \fBabsl::Duration\fP, we can infer that the second should also be interpreted as an \fBabsl::Duration\fP, and make that inference explicit. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Original \- Subtraction in the double domain double x; absl::Duration d; double result = absl::ToDoubleSeconds(d) \- x; // Suggestion \- Subtraction in the absl::Duration domain instead double result = absl::ToDoubleSeconds(d \- absl::Seconds(x)); // Original \- Subtraction of two Durations in the double domain absl::Duration d1, d2; double result = absl::ToDoubleSeconds(d1) \- absl::ToDoubleSeconds(d2); // Suggestion \- Subtraction in the absl::Duration domain instead double result = absl::ToDoubleSeconds(d1 \- d2); .ft P .fi .UNINDENT .UNINDENT .sp Note: As with other \fBclang\-tidy\fP checks, it is possible that multiple fixes may overlap (as in the case of nested expressions), so not all occurrences can be transformed in one run. In particular, this may occur for nested subtraction expressions. Running \fBclang\-tidy\fP multiple times will find and fix these overlaps. .SS abseil\-duration\-unnecessary\-conversion .sp Finds and fixes cases where \fBabsl::Duration\fP values are being converted to numeric types and back again. .sp Floating\-point examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Original \- Conversion to double and back again absl::Duration d1; absl::Duration d2 = absl::Seconds(absl::ToDoubleSeconds(d1)); // Suggestion \- Remove unnecessary conversions absl::Duration d2 = d1; // Original \- Division to convert to double and back again absl::Duration d2 = absl::Seconds(absl::FDivDuration(d1, absl::Seconds(1))); // Suggestion \- Remove division and conversion absl::Duration d2 = d1; .ft P .fi .UNINDENT .UNINDENT .sp Integer examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Original \- Conversion to integer and back again absl::Duration d1; absl::Duration d2 = absl::Hours(absl::ToInt64Hours(d1)); // Suggestion \- Remove unnecessary conversions absl::Duration d2 = d1; // Original \- Integer division followed by conversion absl::Duration d2 = absl::Seconds(d1 / absl::Seconds(1)); // Suggestion \- Remove division and conversion absl::Duration d2 = d1; .ft P .fi .UNINDENT .UNINDENT .sp Unwrapping scalar operations: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Original \- Multiplication by a scalar absl::Duration d1; absl::Duration d2 = absl::Seconds(absl::ToInt64Seconds(d1) * 2); // Suggestion \- Remove unnecessary conversion absl::Duration d2 = d1 * 2; .ft P .fi .UNINDENT .UNINDENT .sp Note: Converting to an integer and back to an \fBabsl::Duration\fP might be a truncating operation if the value is not aligned to the scale of conversion. In the rare case where this is the intended result, callers should use \fBabsl::Trunc\fP to truncate explicitly. .SS abseil\-faster\-strsplit\-delimiter .sp Finds instances of \fBabsl::StrSplit()\fP or \fBabsl::MaxSplits()\fP where the delimiter is a single character string literal and replaces with a character. The check will offer a suggestion to change the string literal into a character. It will also catch code using \fBabsl::ByAnyChar()\fP for just a single character and will transform that into a single character as well. .sp These changes will give the same result, but using characters rather than single character string literals is more efficient and readable. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Original \- the argument is a string literal. for (auto piece : absl::StrSplit(str, \(dqB\(dq)) { // Suggested \- the argument is a character, which causes the more efficient // overload of absl::StrSplit() to be used. for (auto piece : absl::StrSplit(str, \(aqB\(aq)) { // Original \- the argument is a string literal inside absl::ByAnyChar call. for (auto piece : absl::StrSplit(str, absl::ByAnyChar(\(dqB\(dq))) { // Suggested \- the argument is a character, which causes the more efficient // overload of absl::StrSplit() to be used and we do not need absl::ByAnyChar // anymore. for (auto piece : absl::StrSplit(str, \(aqB\(aq)) { // Original \- the argument is a string literal inside absl::MaxSplits call. for (auto piece : absl::StrSplit(str, absl::MaxSplits(\(dqB\(dq, 1))) { // Suggested \- the argument is a character, which causes the more efficient // overload of absl::StrSplit() to be used. for (auto piece : absl::StrSplit(str, absl::MaxSplits(\(aqB\(aq, 1))) { .ft P .fi .UNINDENT .UNINDENT .SS abseil\-no\-internal\-dependencies .sp Warns if code using Abseil depends on internal details. If something is in a namespace that includes the word \(dqinternal\(dq, code is not allowed to depend upon it because it\(aqs an implementation detail. They cannot friend it, include it, you mention it or refer to it in any way. Doing so violates Abseil\(aqs compatibility guidelines and may result in breakage. See \fI\%https://abseil.io/about/compatibility\fP for more information. .sp The following cases will result in warnings: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C absl::strings_internal::foo(); // warning triggered on this line class foo { friend struct absl::container_internal::faa; // warning triggered on this line }; absl::memory_internal::MakeUniqueResult(); // warning triggered on this line .ft P .fi .UNINDENT .UNINDENT .SS abseil\-no\-namespace .sp Ensures code does not open \fBnamespace absl\fP as that violates Abseil\(aqs compatibility guidelines. Code should not open \fBnamespace absl\fP as that conflicts with Abseil\(aqs compatibility guidelines and may result in breakage. .sp Any code that uses: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C namespace absl { ... } .ft P .fi .UNINDENT .UNINDENT .sp will be prompted with a warning. .sp See \fI\%the full Abseil compatibility guidelines\fP for more information. .SS abseil\-redundant\-strcat\-calls .sp Suggests removal of unnecessary calls to \fBabsl::StrCat\fP when the result is being passed to another call to \fBabsl::StrCat\fP or \fBabsl::StrAppend\fP\&. .sp The extra calls cause unnecessary temporary strings to be constructed. Removing them makes the code smaller and faster. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string s = absl::StrCat(\(dqA\(dq, absl::StrCat(\(dqB\(dq, absl::StrCat(\(dqC\(dq, \(dqD\(dq))); //before std::string s = absl::StrCat(\(dqA\(dq, \(dqB\(dq, \(dqC\(dq, \(dqD\(dq); //after absl::StrAppend(&s, absl::StrCat(\(dqE\(dq, \(dqF\(dq, \(dqG\(dq)); //before absl::StrAppend(&s, \(dqE\(dq, \(dqF\(dq, \(dqG\(dq); //after .ft P .fi .UNINDENT .UNINDENT .SS abseil\-str\-cat\-append .sp Flags uses of \fBabsl::StrCat()\fP to append to a \fBstd::string\fP\&. Suggests \fBabsl::StrAppend()\fP should be used instead. .sp The extra calls cause unnecessary temporary strings to be constructed. Removing them makes the code smaller and faster. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C a = absl::StrCat(a, b); // Use absl::StrAppend(&a, b) instead. .ft P .fi .UNINDENT .UNINDENT .sp Does not diagnose cases where \fBabsl::StrCat()\fP is used as a template argument for a functor. .SS abseil\-string\-find\-startswith .sp Checks whether a \fBstd::string::find()\fP or \fBstd::string::rfind()\fP result is compared with 0, and suggests replacing with \fBabsl::StartsWith()\fP\&. This is both a readability and performance issue. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C string s = \(dq...\(dq; if (s.find(\(dqHello World\(dq) == 0) { /* do something */ } if (s.rfind(\(dqHello World\(dq, 0) == 0) { /* do something */ } .ft P .fi .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C string s = \(dq...\(dq; if (absl::StartsWith(s, \(dqHello World\(dq)) { /* do something */ } if (absl::StartsWith(s, \(dqHello World\(dq)) { /* do something */ } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B StringLikeClasses Semicolon\-separated list of names of string\-like classes. By default only \fBstd::basic_string\fP is considered. The list of methods to considered is fixed. .UNINDENT .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B AbseilStringsMatchHeader The location of Abseil\(aqs \fBstrings/match.h\fP\&. Defaults to \fBabsl/strings/match.h\fP\&. .UNINDENT .SS abseil\-string\-find\-str\-contains .sp Finds \fBs.find(...) == string::npos\fP comparisons (for various string\-like types) and suggests replacing with \fBabsl::StrContains()\fP\&. .sp This improves readability and reduces the likelihood of accidentally mixing \fBfind()\fP and \fBnpos\fP from different string\-like types. .sp By default, \(dqstring\-like types\(dq includes \fB::std::basic_string\fP, \fB::std::basic_string_view\fP, and \fB::absl::string_view\fP\&. See the StringLikeClasses option to change this. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string s = \(dq...\(dq; if (s.find(\(dqHello World\(dq) == std::string::npos) { /* do something */ } absl::string_view a = \(dq...\(dq; if (absl::string_view::npos != a.find(\(dqHello World\(dq)) { /* do something */ } .ft P .fi .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string s = \(dq...\(dq; if (!absl::StrContains(s, \(dqHello World\(dq)) { /* do something */ } absl::string_view a = \(dq...\(dq; if (absl::StrContains(a, \(dqHello World\(dq)) { /* do something */ } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B StringLikeClasses Semicolon\-separated list of names of string\-like classes. By default includes \fB::std::basic_string\fP, \fB::std::basic_string_view\fP, and \fB::absl::string_view\fP\&. .UNINDENT .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B AbseilStringsMatchHeader The location of Abseil\(aqs \fBstrings/match.h\fP\&. Defaults to \fBabsl/strings/match.h\fP\&. .UNINDENT .SS abseil\-time\-comparison .sp Prefer comparisons in the \fBabsl::Time\fP domain instead of the integer domain. .sp N.B.: In cases where an \fBabsl::Time\fP is being converted to an integer, alignment may occur. If the comparison depends on this alignment, doing the comparison in the \fBabsl::Time\fP domain may yield a different result. In practice this is very rare, and still indicates a bug which should be fixed. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Original \- Comparison in the integer domain int x; absl::Time t; if (x < absl::ToUnixSeconds(t)) ... // Suggested \- Compare in the absl::Time domain instead if (absl::FromUnixSeconds(x) < t) ... .ft P .fi .UNINDENT .UNINDENT .SS abseil\-time\-subtraction .sp Finds and fixes \fBabsl::Time\fP subtraction expressions to do subtraction in the Time domain instead of the numeric domain. .sp There are two cases of Time subtraction in which deduce additional type information: .INDENT 0.0 .IP \(bu 2 When the result is an \fBabsl::Duration\fP and the first argument is an \fBabsl::Time\fP\&. .IP \(bu 2 When the second argument is a \fBabsl::Time\fP\&. .UNINDENT .sp In the first case, we must know the result of the operation, since without that the second operand could be either an \fBabsl::Time\fP or an \fBabsl::Duration\fP\&. In the second case, the first operand \fImust\fP be an \fBabsl::Time\fP, because subtracting an \fBabsl::Time\fP from an \fBabsl::Duration\fP is not defined. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int x; absl::Time t; // Original \- absl::Duration result and first operand is an absl::Time. absl::Duration d = absl::Seconds(absl::ToUnixSeconds(t) \- x); // Suggestion \- Perform subtraction in the Time domain instead. absl::Duration d = t \- absl::FromUnixSeconds(x); // Original \- Second operand is an absl::Time. int i = x \- absl::ToUnixSeconds(t); // Suggestion \- Perform subtraction in the Time domain instead. int i = absl::ToInt64Seconds(absl::FromUnixSeconds(x) \- t); .ft P .fi .UNINDENT .UNINDENT .SS abseil\-upgrade\-duration\-conversions .sp Finds calls to \fBabsl::Duration\fP arithmetic operators and factories whose argument needs an explicit cast to continue compiling after upcoming API changes. .sp The operators \fB*=\fP, \fB/=\fP, \fB*\fP, and \fB/\fP for \fBabsl::Duration\fP currently accept an argument of class type that is convertible to an arithmetic type. Such a call currently converts the value to an \fBint64_t\fP, even in a case such as \fBstd::atomic\fP that would result in lossy conversion. .sp Additionally, the \fBabsl::Duration\fP factory functions (\fBabsl::Hours\fP, \fBabsl::Minutes\fP, etc) currently accept an \fBint64_t\fP or a floating\-point type. Similar to the arithmetic operators, calls with an argument of class type that is convertible to an arithmetic type go through the \fBint64_t\fP path. .sp These operators and factories will be changed to only accept arithmetic types to prevent unintended behavior. After these changes are released, passing an argument of class type will no longer compile, even if the type is implicitly convertible to an arithmetic type. .sp Here are example fixes created by this check: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::atomic a; absl::Duration d = absl::Milliseconds(a); d *= a; .ft P .fi .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::atomic a; absl::Duration d = absl::Milliseconds(static_cast(a)); d *= static_cast(a); .ft P .fi .UNINDENT .UNINDENT .sp Note that this check always adds a cast to \fBint64_t\fP in order to preserve the current behavior of user code. It is possible that this uncovers unintended behavior due to types implicitly convertible to a floating\-point type. .SS altera\-id\-dependent\-backward\-branch .sp Finds ID\-dependent variables and fields that are used within loops. This causes branches to occur inside the loops, and thus leads to performance degradation. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // The following code will produce a warning because this ID\-dependent // variable is used in a loop condition statement. int ThreadID = get_local_id(0); // The following loop will produce a warning because the loop condition // statement depends on an ID\-dependent variable. for (int i = 0; i < ThreadID; ++i) { std::cout << i << std::endl; } // The following loop will not produce a warning, because the ID\-dependent // variable is not used in the loop condition statement. for (int i = 0; i < 100; ++i) { std::cout << ThreadID << std::endl; } .ft P .fi .UNINDENT .UNINDENT .sp Based on the \fI\%Altera SDK for OpenCL: Best Practices Guide\fP\&. .SS altera\-kernel\-name\-restriction .sp Finds kernel files and include directives whose filename is \fIkernel.cl\fP, \fIVerilog.cl\fP, or \fIVHDL.cl\fP\&. The check is case insensitive. .sp Such kernel file names cause the offline compiler to generate intermediate design files that have the same names as certain internal files, which leads to a compilation error. .sp Based on the \fIGuidelines for Naming the Kernel\fP section in the \fI\%Intel FPGA SDK for OpenCL Pro Edition: Programming Guide\fP\&. .SS altera\-single\-work\-item\-barrier .sp Finds OpenCL kernel functions that call a barrier function but do not call an ID function (\fBget_local_id\fP, \fBget_local_id\fP, \fBget_group_id\fP, or \fBget_local_linear_id\fP). .sp These kernels may be viable single work\-item kernels, but will be forced to execute as NDRange kernels if using a newer version of the Altera Offline Compiler (>= v17.01). .sp If using an older version of the Altera Offline Compiler, these kernel functions will be treated as single work\-item kernels, which could be inefficient or lead to errors if NDRange semantics were intended. .sp Based on the \fI\%Altera SDK for OpenCL: Best Practices Guide\fP\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // error: function calls barrier but does not call an ID function. void __kernel barrier_no_id(__global int * foo, int size) { for (int i = 0; i < 100; i++) { foo[i] += 5; } barrier(CLK_GLOBAL_MEM_FENCE); } // ok: function calls barrier and an ID function. void __kernel barrier_with_id(__global int * foo, int size) { for (int i = 0; i < 100; i++) { int tid = get_global_id(0); foo[tid] += 5; } barrier(CLK_GLOBAL_MEM_FENCE); } // ok with AOC Version 17.01: the reqd_work_group_size turns this into // an NDRange. __attribute__((reqd_work_group_size(2,2,2))) void __kernel barrier_with_id(__global int * foo, int size) { for (int i = 0; i < 100; i++) { foo[tid] += 5; } barrier(CLK_GLOBAL_MEM_FENCE); } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B AOCVersion Defines the version of the Altera Offline Compiler. Defaults to \fB1600\fP (corresponding to version 16.00). .UNINDENT .SS altera\-struct\-pack\-align .sp Finds structs that are inefficiently packed or aligned, and recommends packing and/or aligning of said structs as needed. .sp Structs that are not packed take up more space than they should, and accessing structs that are not well aligned is inefficient. .sp Fix\-its are provided to fix both of these issues by inserting and/or amending relevant struct attributes. .sp Based on the \fI\%Altera SDK for OpenCL: Best Practices Guide\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // The following struct is originally aligned to 4 bytes, and thus takes up // 12 bytes of memory instead of 10. Packing the struct will make it use // only 10 bytes of memory, and aligning it to 16 bytes will make it // efficient to access. struct example { char a; // 1 byte double b; // 8 bytes char c; // 1 byte }; // The following struct is arranged in such a way that packing is not needed. // However, it is aligned to 4 bytes instead of 8, and thus needs to be // explicitly aligned. struct implicitly_packed_example { char a; // 1 byte char b; // 1 byte char c; // 1 byte char d; // 1 byte int e; // 4 bytes }; // The following struct is explicitly aligned and packed. struct good_example { char a; // 1 byte double b; // 8 bytes char c; // 1 byte } __attribute__((packed)) __attribute__((aligned(16)); // Explicitly aligning a struct to the wrong value will result in a warning. // The following example should be aligned to 16 bytes, not 32. struct badly_aligned_example { char a; // 1 byte double b; // 8 bytes char c; // 1 byte } __attribute__((packed)) __attribute__((aligned(32))); .ft P .fi .UNINDENT .UNINDENT .SS altera\-unroll\-loops .sp Finds inner loops that have not been unrolled, as well as fully unrolled loops with unknown loop bounds or a large number of iterations. .sp Unrolling inner loops could improve the performance of OpenCL kernels. However, if they have unknown loop bounds or a large number of iterations, they cannot be fully unrolled, and should be partially unrolled. .sp Notes: .INDENT 0.0 .IP \(bu 2 This check is unable to determine the number of iterations in a \fBwhile\fP or \fBdo..while\fP loop; hence if such a loop is fully unrolled, a note is emitted advising the user to partially unroll instead. .IP \(bu 2 In \fBfor\fP loops, our check only works with simple arithmetic increments ( \fB+\fP, \fB\-\fP, \fB*\fP, \fB/\fP). For all other increments, partial unrolling is advised. .IP \(bu 2 Depending on the exit condition, the calculations for determining if the number of iterations is large may be off by 1. This should not be an issue since the cut\-off is generally arbitrary. .UNINDENT .sp Based on the \fI\%Altera SDK for OpenCL: Best Practices Guide\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C for (int i = 0; i < 10; i++) { // ok: outer loops should not be unrolled int j = 0; do { // warning: this inner do..while loop should be unrolled j++; } while (j < 15); int k = 0; #pragma unroll while (k < 20) { // ok: this inner loop is already unrolled k++; } } int A[1000]; #pragma unroll // warning: this loop is large and should be partially unrolled for (int a : A) { printf(\(dq%d\(dq, a); } #pragma unroll 5 // ok: this loop is large, but is partially unrolled for (int a : A) { printf(\(dq%d\(dq, a); } #pragma unroll // warning: this loop is large and should be partially unrolled for (int i = 0; i < 1000; ++i) { printf(\(dq%d\(dq, i); } #pragma unroll 5 // ok: this loop is large, but is partially unrolled for (int i = 0; i < 1000; ++i) { printf(\(dq%d\(dq, i); } #pragma unroll // warning: << operator not supported, recommend partial unrolling for (int i = 0; i < 1000; i<<1) { printf(\(dq%d\(dq, i); } std::vector someVector (100, 0); int i = 0; #pragma unroll // note: loop may be large, recommend partial unrolling while (i < someVector.size()) { someVector[i]++; } #pragma unroll // note: loop may be large, recommend partial unrolling while (true) { printf(\(dqIn loop\(dq); } #pragma unroll 5 // ok: loop may be large, but is partially unrolled while (i < someVector.size()) { someVector[i]++; } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B MaxLoopIterations Defines the maximum number of loop iterations that a fully unrolled loop can have. By default, it is set to \fI100\fP\&. .sp In practice, this refers to the integer value of the upper bound within the loop statement\(aqs condition expression. .UNINDENT .SS android\-cloexec\-accept .sp The usage of \fBaccept()\fP is not recommended, it\(aqs better to use \fBaccept4()\fP\&. Without this flag, an opened sensitive file descriptor would remain open across a fork+exec to a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C accept(sockfd, addr, addrlen); // becomes accept4(sockfd, addr, addrlen, SOCK_CLOEXEC); .ft P .fi .UNINDENT .UNINDENT .SS android\-cloexec\-accept4 .sp \fBaccept4()\fP should include \fBSOCK_CLOEXEC\fP in its type argument to avoid the file descriptor leakage. Without this flag, an opened sensitive file would remain open across a fork+exec to a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C accept4(sockfd, addr, addrlen, SOCK_NONBLOCK); // becomes accept4(sockfd, addr, addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC); .ft P .fi .UNINDENT .UNINDENT .SS android\-cloexec\-creat .sp The usage of \fBcreat()\fP is not recommended, it\(aqs better to use \fBopen()\fP\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int fd = creat(path, mode); // becomes int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, mode); .ft P .fi .UNINDENT .UNINDENT .SS android\-cloexec\-dup .sp The usage of \fBdup()\fP is not recommended, it\(aqs better to use \fBfcntl()\fP, which can set the close\-on\-exec flag. Otherwise, an opened sensitive file would remain open across a fork+exec to a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int fd = dup(oldfd); // becomes int fd = fcntl(oldfd, F_DUPFD_CLOEXEC); .ft P .fi .UNINDENT .UNINDENT .SS android\-cloexec\-epoll\-create .sp The usage of \fBepoll_create()\fP is not recommended, it\(aqs better to use \fBepoll_create1()\fP, which allows close\-on\-exec. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C epoll_create(size); // becomes epoll_create1(EPOLL_CLOEXEC); .ft P .fi .UNINDENT .UNINDENT .SS android\-cloexec\-epoll\-create1 .sp \fBepoll_create1()\fP should include \fBEPOLL_CLOEXEC\fP in its type argument to avoid the file descriptor leakage. Without this flag, an opened sensitive file would remain open across a fork+exec to a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C epoll_create1(0); // becomes epoll_create1(EPOLL_CLOEXEC); .ft P .fi .UNINDENT .UNINDENT .SS android\-cloexec\-fopen .sp \fBfopen()\fP should include \fBe\fP in their mode string; so \fBre\fP would be valid. This is equivalent to having set \fBFD_CLOEXEC on\fP that descriptor. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C fopen(\(dqfn\(dq, \(dqr\(dq); // becomes fopen(\(dqfn\(dq, \(dqre\(dq); .ft P .fi .UNINDENT .UNINDENT .SS android\-cloexec\-inotify\-init .sp The usage of \fBinotify_init()\fP is not recommended, it\(aqs better to use \fBinotify_init1()\fP\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C inotify_init(); // becomes inotify_init1(IN_CLOEXEC); .ft P .fi .UNINDENT .UNINDENT .SS android\-cloexec\-inotify\-init1 .sp \fBinotify_init1()\fP should include \fBIN_CLOEXEC\fP in its type argument to avoid the file descriptor leakage. Without this flag, an opened sensitive file would remain open across a fork+exec to a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C inotify_init1(IN_NONBLOCK); // becomes inotify_init1(IN_NONBLOCK | IN_CLOEXEC); .ft P .fi .UNINDENT .UNINDENT .SS android\-cloexec\-memfd\-create .sp \fBmemfd_create()\fP should include \fBMFD_CLOEXEC\fP in its type argument to avoid the file descriptor leakage. Without this flag, an opened sensitive file would remain open across a fork+exec to a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C memfd_create(name, MFD_ALLOW_SEALING); // becomes memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC); .ft P .fi .UNINDENT .UNINDENT .SS android\-cloexec\-open .sp A common source of security bugs is code that opens a file without using the \fBO_CLOEXEC\fP flag. Without that flag, an opened sensitive file would remain open across a fork+exec to a lower\-privileged SELinux domain, leaking that sensitive data. Open\-like functions including \fBopen()\fP, \fBopenat()\fP, and \fBopen64()\fP should include \fBO_CLOEXEC\fP in their flags argument. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C open(\(dqfilename\(dq, O_RDWR); open64(\(dqfilename\(dq, O_RDWR); openat(0, \(dqfilename\(dq, O_RDWR); // becomes open(\(dqfilename\(dq, O_RDWR | O_CLOEXEC); open64(\(dqfilename\(dq, O_RDWR | O_CLOEXEC); openat(0, \(dqfilename\(dq, O_RDWR | O_CLOEXEC); .ft P .fi .UNINDENT .UNINDENT .SS android\-cloexec\-pipe .sp This check detects usage of \fBpipe()\fP\&. Using \fBpipe()\fP is not recommended, \fBpipe2()\fP is the suggested replacement. The check also adds the O_CLOEXEC flag that marks the file descriptor to be closed in child processes. Without this flag a sensitive file descriptor can be leaked to a child process, potentially into a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C pipe(pipefd); .ft P .fi .UNINDENT .UNINDENT .sp Suggested replacement: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C pipe2(pipefd, O_CLOEXEC); .ft P .fi .UNINDENT .UNINDENT .SS android\-cloexec\-pipe2 .sp This check ensures that pipe2() is called with the O_CLOEXEC flag. The check also adds the O_CLOEXEC flag that marks the file descriptor to be closed in child processes. Without this flag a sensitive file descriptor can be leaked to a child process, potentially into a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C pipe2(pipefd, O_NONBLOCK); .ft P .fi .UNINDENT .UNINDENT .sp Suggested replacement: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C pipe2(pipefd, O_NONBLOCK | O_CLOEXEC); .ft P .fi .UNINDENT .UNINDENT .SS android\-cloexec\-socket .sp \fBsocket()\fP should include \fBSOCK_CLOEXEC\fP in its type argument to avoid the file descriptor leakage. Without this flag, an opened sensitive file would remain open across a fork+exec to a lower\-privileged SELinux domain. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C socket(domain, type, SOCK_STREAM); // becomes socket(domain, type, SOCK_STREAM | SOCK_CLOEXEC); .ft P .fi .UNINDENT .UNINDENT .SS android\-comparison\-in\-temp\-failure\-retry .sp Diagnoses comparisons that appear to be incorrectly placed in the argument to the \fBTEMP_FAILURE_RETRY\fP macro. Having such a use is incorrect in the vast majority of cases, and will often silently defeat the purpose of the \fBTEMP_FAILURE_RETRY\fP macro. .sp For context, \fBTEMP_FAILURE_RETRY\fP is \fI\%a convenience macro\fP provided by both glibc and Bionic. Its purpose is to repeatedly run a syscall until it either succeeds, or fails for reasons other than being interrupted. .sp Example buggy usage looks like: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C char cs[1]; while (TEMP_FAILURE_RETRY(read(STDIN_FILENO, cs, sizeof(cs)) != 0)) { // Do something with cs. } .ft P .fi .UNINDENT .UNINDENT .sp Because TEMP_FAILURE_RETRY will check for whether the result \fIof the comparison\fP is \fB\-1\fP, and retry if so. .sp If you encounter this, the fix is simple: lift the comparison out of the \fBTEMP_FAILURE_RETRY\fP argument, like so: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C char cs[1]; while (TEMP_FAILURE_RETRY(read(STDIN_FILENO, cs, sizeof(cs))) != 0) { // Do something with cs. } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B RetryMacros A comma\-separated list of the names of retry macros to be checked. .UNINDENT .SS boost\-use\-to\-string .sp This check finds conversion from integer type like \fBint\fP to \fBstd::string\fP or \fBstd::wstring\fP using \fBboost::lexical_cast\fP, and replace it with calls to \fBstd::to_string\fP and \fBstd::to_wstring\fP\&. .sp It doesn\(aqt replace conversion from floating points despite the \fBto_string\fP overloads, because it would change the behavior. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C auto str = boost::lexical_cast(42); auto wstr = boost::lexical_cast(2137LL); // Will be changed to auto str = std::to_string(42); auto wstr = std::to_wstring(2137LL); .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-argument\-comment .sp Checks that argument comments match parameter names. .sp The check understands argument comments in the form \fB/*parameter_name=*/\fP that are placed right before the argument. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(bool foo); \&... f(/*bar=*/true); // warning: argument name \(aqbar\(aq in comment does not match parameter name \(aqfoo\(aq .ft P .fi .UNINDENT .UNINDENT .sp The check tries to detect typos and suggest automated fixes for them. .SS Options .INDENT 0.0 .TP .B StrictMode When \fIfalse\fP (default value), the check will ignore leading and trailing underscores and case when comparing names \-\- otherwise they are taken into account. .UNINDENT .INDENT 0.0 .TP .B IgnoreSingleArgument When \fItrue\fP, the check will ignore the single argument. .UNINDENT .INDENT 0.0 .TP .B CommentBoolLiterals When \fItrue\fP, the check will add argument comments in the format \fB/*ParameterName=*/\fP right before the boolean literal argument. .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(bool TurnKey, bool PressButton); foo(true, false); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(bool TurnKey, bool PressButton); foo(/*TurnKey=*/true, /*PressButton=*/false); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CommentIntegerLiterals When true, the check will add argument comments in the format \fB/*ParameterName=*/\fP right before the integer literal argument. .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(int MeaningOfLife); foo(42); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(int MeaningOfLife); foo(/*MeaningOfLife=*/42); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CommentFloatLiterals When true, the check will add argument comments in the format \fB/*ParameterName=*/\fP right before the float/double literal argument. .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(float Pi); foo(3.14159); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(float Pi); foo(/*Pi=*/3.14159); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CommentStringLiterals When true, the check will add argument comments in the format \fB/*ParameterName=*/\fP right before the string literal argument. .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(const char *String); void foo(const wchar_t *WideString); foo(\(dqHello World\(dq); foo(L\(dqHello World\(dq); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(const char *String); void foo(const wchar_t *WideString); foo(/*String=*/\(dqHello World\(dq); foo(/*WideString=*/L\(dqHello World\(dq); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CommentCharacterLiterals When true, the check will add argument comments in the format \fB/*ParameterName=*/\fP right before the character literal argument. .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(char *Character); foo(\(aqA\(aq); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(char *Character); foo(/*Character=*/\(aqA\(aq); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CommentUserDefinedLiterals When true, the check will add argument comments in the format \fB/*ParameterName=*/\fP right before the user defined literal argument. .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(double Distance); double operator\(dq\(dq _km(long double); foo(402.0_km); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(double Distance); double operator\(dq\(dq _km(long double); foo(/*Distance=*/402.0_km); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CommentNullPtrs When true, the check will add argument comments in the format \fB/*ParameterName=*/\fP right before the nullptr literal argument. .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(A* Value); foo(nullptr); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(A* Value); foo(/*Value=*/nullptr); .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-assert\-side\-effect .sp Finds \fBassert()\fP with side effect. .sp The condition of \fBassert()\fP is evaluated only in debug builds so a condition with side effect can cause different behavior in debug / release builds. .SS Options .INDENT 0.0 .TP .B AssertMacros A comma\-separated list of the names of assert macros to be checked. .UNINDENT .INDENT 0.0 .TP .B CheckFunctionCalls Whether to treat non\-const member and non\-member functions as they produce side effects. Disabled by default because it can increase the number of false positive warnings. .UNINDENT .INDENT 0.0 .TP .B IgnoredFunctions A semicolon\-separated list of the names of functions or methods to be considered as not having side\-effects. Regular expressions are accepted, e.g. \fI[Rr]ef(erence)?$\fP matches every type with suffix \fIRef\fP, \fIref\fP, \fIReference\fP and \fIreference\fP\&. The default is empty. If a name in the list contains the sequence \fI::\fP it is matched against the qualified typename (i.e. \fInamespace::Type\fP, otherwise it is matched against only the type name (i.e. \fIType\fP). .UNINDENT .SS bugprone\-assignment\-in\-if\-condition .sp Finds assignments within conditions of \fIif\fP statements. Such assignments are bug\-prone because they may have been intended as equality tests. .sp This check finds all assignments within \fIif\fP conditions, including ones that are not flagged by \fI\-Wparentheses\fP due to an extra set of parentheses, and including assignments that call an overloaded \fIoperator=()\fP\&. The identified assignments violate \fI\%BARR group \(dqRule 8.2.c\(dq\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int f = 3; if(f = 4) { // This is identified by both \(gaWparentheses\(ga and this check \- should it have been: \(gaif (f == 4)\(ga ? f = f + 1; } if((f == 5) || (f = 6)) { // the assignment here \(ga(f = 6)\(ga is identified by this check, but not by \(ga\-Wparentheses\(ga. Should it have been \(ga(f == 6)\(ga ? f = f + 2; } .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-bad\-signal\-to\-kill\-thread .sp Finds \fBpthread_kill\fP function calls when a thread is terminated by raising \fBSIGTERM\fP signal and the signal kills the entire process, not just the individual thread. Use any signal except \fBSIGTERM\fP\&. .sp This check corresponds to the CERT C Coding Standard rule \fI\%POS44\-C. Do not use signals to terminate threads\fP\&. .SS bugprone\-bool\-pointer\-implicit\-conversion .sp Checks for conditions based on implicit conversion from a \fBbool\fP pointer to \fBbool\fP\&. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bool *p; if (p) { // Never used in a pointer\-specific way. } .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-branch\-clone .sp Checks for repeated branches in \fBif/else if/else\fP chains, consecutive repeated branches in \fBswitch\fP statements and identical true and false branches in conditional operators. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (test_value(x)) { y++; do_something(x, y); } else { y++; do_something(x, y); } .ft P .fi .UNINDENT .UNINDENT .sp In this simple example (which could arise e.g. as a copy\-paste error) the \fBthen\fP and \fBelse\fP branches are identical and the code is equivalent the following shorter and cleaner code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C test_value(x); // can be omitted unless it has side effects y++; do_something(x, y); .ft P .fi .UNINDENT .UNINDENT .sp If this is the intended behavior, then there is no reason to use a conditional statement; otherwise the issue can be solved by fixing the branch that is handled incorrectly. .sp The check also detects repeated branches in longer \fBif/else if/else\fP chains where it would be even harder to notice the problem. .sp In \fBswitch\fP statements the check only reports repeated branches when they are consecutive, because it is relatively common that the \fBcase:\fP labels have some natural ordering and rearranging them would decrease the readability of the code. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C switch (ch) { case \(aqa\(aq: return 10; case \(aqA\(aq: return 10; case \(aqb\(aq: return 11; case \(aqB\(aq: return 11; default: return 10; } .ft P .fi .UNINDENT .UNINDENT .sp Here the check reports that the \fB\(aqa\(aq\fP and \fB\(aqA\(aq\fP branches are identical (and that the \fB\(aqb\(aq\fP and \fB\(aqB\(aq\fP branches are also identical), but does not report that the \fBdefault:\fP branch is also identical to the first two branches. If this is indeed the correct behavior, then it could be implemented as: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C switch (ch) { case \(aqa\(aq: case \(aqA\(aq: return 10; case \(aqb\(aq: case \(aqB\(aq: return 11; default: return 10; } .ft P .fi .UNINDENT .UNINDENT .sp Here the check does not warn for the repeated \fBreturn 10;\fP, which is good if we want to preserve that \fB\(aqa\(aq\fP is before \fB\(aqb\(aq\fP and \fBdefault:\fP is the last branch. .sp Switch cases marked with the \fB[[fallthrough]]\fP attribute are ignored. .sp Finally, the check also examines conditional operators and reports code like: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C return test_value(x) ? x : x; .ft P .fi .UNINDENT .UNINDENT .sp Unlike if statements, the check does not detect chains of conditional operators. .sp Note: This check also reports situations where branches become identical only after preprocessing. .SS bugprone\-copy\-constructor\-init .sp Finds copy constructors where the constructor doesn\(aqt call the copy constructor of the base class. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Copyable { public: Copyable() = default; Copyable(const Copyable &) = default; int memberToBeCopied = 0; }; class X2 : public Copyable { X2(const X2 &other) {} // Copyable(other) is missing }; .ft P .fi .UNINDENT .UNINDENT .sp Also finds copy constructors where the constructor of the base class don\(aqt have parameter. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class X3 : public Copyable { X3(const X3 &other) : Copyable() {} // other is missing }; .ft P .fi .UNINDENT .UNINDENT .sp Failure to properly initialize base class sub\-objects during copy construction can result in undefined behavior, crashes, data corruption, or other unexpected outcomes. The check ensures that the copy constructor of a derived class properly calls the copy constructor of the base class, helping to prevent bugs and improve code quality. .sp Limitations: .INDENT 0.0 .IP \(bu 2 It won\(aqt generate warnings for empty classes, as there are no class members (including base class sub\-objects) to worry about. .IP \(bu 2 It won\(aqt generate warnings for base classes that have copy constructor private or deleted. .IP \(bu 2 It won\(aqt generate warnings for base classes that are initialized using other non\-default constructor, as this could be intentional. .UNINDENT .sp The check also suggests a fix\-its in some cases. .SS bugprone\-dangling\-handle .sp Detect dangling references in value handles like \fBstd::string_view\fP\&. These dangling references can be a result of constructing handles from temporary values, where the temporary is destroyed soon after the handle is created. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C string_view View = string(); // View will dangle. string A; View = A + \(dqA\(dq; // still dangle. vector V; V.push_back(string()); // V[0] is dangling. V.resize(3, string()); // V[1] and V[2] will also dangle. string_view f() { // All these return values will dangle. return string(); string S; return S; char Array[10]{}; return Array; } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B HandleClasses A semicolon\-separated list of class names that should be treated as handles. By default only \fBstd::basic_string_view\fP and \fBstd::experimental::basic_string_view\fP are considered. .UNINDENT .SS bugprone\-dynamic\-static\-initializers .sp Finds instances of static variables that are dynamically initialized in header files. .sp This can pose problems in certain multithreaded contexts. For example, when disabling compiler generated synchronization instructions for static variables initialized at runtime (e.g. by \fB\-fno\-threadsafe\-statics\fP), even if a particular project takes the necessary precautions to prevent race conditions during initialization by providing their own synchronization, header files included from other projects may not. Therefore, such a check is helpful for ensuring that disabling compiler generated synchronization for static variable initialization will not cause problems. .sp Consider the following code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int foo() { static int k = bar(); return k; } .ft P .fi .UNINDENT .UNINDENT .sp When synchronization of static initialization is disabled, if two threads both call \fIfoo\fP for the first time, there is the possibility that \fIk\fP will be double initialized, creating a race condition. .SS bugprone\-easily\-swappable\-parameters .sp Finds function definitions where parameters of convertible types follow each other directly, making call sites prone to calling the function with swapped (or badly ordered) arguments. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void drawPoint(int X, int Y) { /* ... */ } FILE *open(const char *Dir, const char *Name, Flags Mode) { /* ... */ } .ft P .fi .UNINDENT .UNINDENT .sp A potential call like \fBdrawPoint(\-2, 5)\fP or \fBopenPath(\(dqa.txt\(dq, \(dqtmp\(dq, Read)\fP is perfectly legal from the language\(aqs perspective, but might not be what the developer of the function intended. .sp More elaborate and type\-safe constructs, such as opaque typedefs or strong types should be used instead, to prevent a mistaken order of arguments. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct Coord2D { int X; int Y; }; void drawPoint(const Coord2D Pos) { /* ... */ } FILE *open(const Path &Dir, const Filename &Name, Flags Mode) { /* ... */ } .ft P .fi .UNINDENT .UNINDENT .sp Due to the potentially elaborate refactoring and API\-breaking that is necessary to strengthen the type safety of a project, no automatic fix\-its are offered. .SS Options .SS Extension/relaxation options .sp Relaxation (or extension) options can be used to broaden the scope of the analysis and fine\-tune the enabling of more mixes between types. Some mixes may depend on coding style or preference specific to a project, however, it should be noted that enabling \fIall\fP of these relaxations model the way of mixing at call sites the most. These options are expected to make the check report for more functions, and report longer mixable ranges. .INDENT 0.0 .TP .B QualifiersMix Whether to consider parameters of some \fIcvr\-qualified\fP \fBT\fP and a differently \fIcvr\-qualified\fP \fBT\fP (i.e. \fBT\fP and \fBconst T\fP, \fBconst T\fP and \fBvolatile T\fP, etc.) mixable between one another. If \fIfalse\fP, the check will consider differently qualified types unmixable. \fITrue\fP turns the warnings on. Defaults to \fIfalse\fP\&. .sp The following example produces a diagnostic only if \fIQualifiersMix\fP is enabled: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C void *memcpy(const void *Destination, void *Source, std::size_t N) { /* ... */ } .ft P .fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ModelImplicitConversions Whether to consider parameters of type \fBT\fP and \fBU\fP mixable if there exists an implicit conversion from \fBT\fP to \fBU\fP and \fBU\fP to \fBT\fP\&. If \fIfalse\fP, the check will not consider implicitly convertible types for mixability. \fITrue\fP turns warnings for implicit conversions on. Defaults to \fItrue\fP\&. .sp The following examples produce a diagnostic only if \fIModelImplicitConversions\fP is enabled: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C void fun(int Int, double Double) { /* ... */ } void compare(const char *CharBuf, std::string String) { /* ... */ } .ft P .fi .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 Changing the qualifiers of an expression\(aqs type (e.g. from \fBint\fP to \fBconst int\fP) is defined as an \fIimplicit conversion\fP in the C++ Standard. However, the check separates this decision\-making on the mixability of differently qualified types based on whether \fIQualifiersMix\fP was enabled. .sp For example, the following code snippet will only produce a diagnostic if \fBboth\fP \fIQualifiersMix\fP and \fIModelImplicitConversions\fP are enabled: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void fun2(int Int, const double Double) { /* ... */ } .ft P .fi .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .SS Filtering options .sp Filtering options can be used to lessen the size of the diagnostics emitted by the checker, whether the aim is to ignore certain constructs or dampen the noisiness. .INDENT 0.0 .TP .B MinimumLength The minimum length required from an adjacent parameter sequence to be diagnosed. Defaults to \fI2\fP\&. Might be any positive integer greater or equal to \fI2\fP\&. If \fI0\fP or \fI1\fP is given, the default value \fI2\fP will be used instead. .sp For example, if \fI3\fP is specified, the examples above will not be matched. .UNINDENT .INDENT 0.0 .TP .B IgnoredParameterNames The list of parameter \fBnames\fP that should never be considered part of a swappable adjacent parameter sequence. The value is a \fI;\fP\-separated list of names. To ignore unnamed parameters, add \fI\(dq\(dq\fP to the list verbatim (not the empty string, but the two quotes, potentially escaped!). \fBThis option is case\-sensitive!\fP .sp By default, the following parameter names, and their Uppercase\-initial variants are ignored: \fI\(dq\(dq\fP (unnamed parameters), \fIiterator\fP, \fIbegin\fP, \fIend\fP, \fIfirst\fP, \fIlast\fP, \fIlhs\fP, \fIrhs\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoredParameterTypeSuffixes The list of parameter \fBtype name suffixes\fP that should never be considered part of a swappable adjacent parameter sequence. Parameters which type, as written in the source code, end with an element of this option will be ignored. The value is a \fI;\fP\-separated list of names. \fBThis option is case\-sensitive!\fP .sp By default, the following, and their lowercase\-initial variants are ignored: \fIbool\fP, \fIIt\fP, \fIIterator\fP, \fIInputIt\fP, \fIForwardIt\fP, \fIBidirIt\fP, \fIRandomIt\fP, \fIrandom_iterator\fP, \fIReverseIt\fP, \fIreverse_iterator\fP, \fIreverse_const_iterator\fP, \fIRandomIt\fP, \fIrandom_iterator\fP, \fIReverseIt\fP, \fIreverse_iterator\fP, \fIreverse_const_iterator\fP, \fIConst_Iterator\fP, \fIConstIterator\fP, \fIconst_reverse_iterator\fP, \fIConstReverseIterator\fP\&. In addition, \fI_Bool\fP (but not \fI_bool\fP) is also part of the default value. .UNINDENT .INDENT 0.0 .TP .B SuppressParametersUsedTogether Suppresses diagnostics about parameters that are used together or in a similar fashion inside the function\(aqs body. Defaults to \fItrue\fP\&. Specifying \fIfalse\fP will turn off the heuristics. .sp Currently, the following heuristics are implemented which will suppress the warning about the parameter pair involved: .INDENT 7.0 .IP \(bu 2 The parameters are used in the same expression, e.g. \fBf(a, b)\fP or \fBa < b\fP\&. .IP \(bu 2 The parameters are further passed to the same function to the same parameter of that function, of the same overload. E.g. \fBf(a, 1)\fP and \fBf(b, 2)\fP to some \fBf(T, int)\fP\&. .sp \fBNOTE:\fP .INDENT 2.0 .INDENT 3.5 The check does not perform path\-sensitive analysis, and as such, \(dqsame function\(dq in this context means the same function declaration. If the same member function of a type on two distinct instances are called with the parameters, it will still be regarded as \(dqsame function\(dq. .UNINDENT .UNINDENT .IP \(bu 2 The same member field is accessed, or member method is called of the two parameters, e.g. \fBa.foo()\fP and \fBb.foo()\fP\&. .IP \(bu 2 Separate \fBreturn\fP statements return either of the parameters on different code paths. .UNINDENT .UNINDENT .INDENT 0.0 .TP .B NamePrefixSuffixSilenceDissimilarityTreshold The number of characters two parameter names might be different on \fIeither\fP the head or the tail end with the rest of the name the same so that the warning about the two parameters are silenced. Defaults to \fI1\fP\&. Might be any positive integer. If \fI0\fP, the filtering heuristic based on the parameters\(aq names is turned off. .sp This option can be used to silence warnings about parameters where the naming scheme indicates that the order of those parameters do not matter. .sp For example, the parameters \fBLHS\fP and \fBRHS\fP are 1\-dissimilar suffixes of each other: \fBL\fP and \fBR\fP is the different character, while \fBHS\fP is the common suffix. Similarly, parameters \fBtext1, text2, text3\fP are 1\-dissimilar prefixes of each other, with the numbers at the end being the dissimilar part. If the value is at least \fI1\fP, such cases will not be reported. .UNINDENT .SS Limitations .sp \fBThis check is designed to check function signatures!\fP .sp The check does not investigate functions that are generated by the compiler in a context that is only determined from a call site. These cases include variadic functions, functions in C code that do not have an argument list, and C++ template instantiations. Most of these cases, which are otherwise swappable from a caller\(aqs standpoint, have no way of getting \(dqfixed\(dq at the definition point. In the case of C++ templates, only primary template definitions and explicit specializations are matched and analyzed. .sp None of the following cases produce a diagnostic: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int printf(const char *Format, ...) { /* ... */ } int someOldCFunction() { /* ... */ } template int add(T X, U Y) { return X + Y }; void theseAreNotWarnedAbout() { printf(\(dq%d %d\en\(dq, 1, 2); // Two ints passed, they could be swapped. someOldCFunction(1, 2, 3); // Similarly, multiple ints passed. add(1, 2); // Instantiates \(aqadd\(aq, but that\(aqs not a user\-defined function. } .ft P .fi .UNINDENT .UNINDENT .sp Due to the limitation above, parameters which type are further dependent upon template instantiations to \fIprove\fP that they mix with another parameter\(aqs is not diagnosed. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C template struct Vector { typedef T element_type; }; // Diagnosed: Explicit instantiation was done by the user, we can prove it // is the same type. void instantiated(int A, Vector::element_type B) { /* ... */ } // Diagnosed: The two parameter types are exactly the same. template void exact(typename Vector::element_type A, typename Vector::element_type B) { /* ... */ } // Skipped: The two parameters are both \(aqT\(aq but we cannot prove this // without actually instantiating. template void falseNegative(T A, typename Vector::element_type B) { /* ... */ } .ft P .fi .UNINDENT .UNINDENT .sp In the context of \fIimplicit conversions\fP (when \fIModelImplicitConversions\fP is enabled), the modelling performed by the check warns if the parameters are swappable and the swapped order matches implicit conversions. It does not model whether there exists an unrelated third type from which \fIboth\fP parameters can be given in a function call. This means that in the following example, even while \fBstrs()\fP clearly carries the possibility to be called with swapped arguments (as long as the arguments are string literals), will not be warned about. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct String { String(const char *Buf); }; struct StringView { StringView(const char *Buf); operator const char *() const; }; // Skipped: Directly swapping expressions of the two type cannot mix. // (Note: StringView \-> const char * \-> String would be **two** // user\-defined conversions, which is disallowed by the language.) void strs(String Str, StringView SV) { /* ... */ } // Diagnosed: StringView implicitly converts to and from a buffer. void cStr(StringView SV, const char *Buf() { /* ... */ } .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-empty\-catch .sp Detects and suggests addressing issues with empty catch statements. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C try { // Some code that can throw an exception } catch(const std::exception&) { } .ft P .fi .UNINDENT .UNINDENT .sp Having empty catch statements in a codebase can be a serious problem that developers should be aware of. Catch statements are used to handle exceptions that are thrown during program execution. When an exception is thrown, the program jumps to the nearest catch statement that matches the type of the exception. .sp Empty catch statements, also known as \(dqswallowing\(dq exceptions, catch the exception but do nothing with it. This means that the exception is not handled properly, and the program continues to run as if nothing happened. This can lead to several issues, such as: .INDENT 0.0 .IP \(bu 2 \fIHidden Bugs\fP: If an exception is caught and ignored, it can lead to hidden bugs that are difficult to diagnose and fix. The root cause of the problem may not be apparent, and the program may continue to behave in unexpected ways. .IP \(bu 2 \fISecurity Issues\fP: Ignoring exceptions can lead to security issues, such as buffer overflows or null pointer dereferences. Hackers can exploit these vulnerabilities to gain access to sensitive data or execute malicious code. .IP \(bu 2 \fIPoor Code Quality\fP: Empty catch statements can indicate poor code quality and a lack of attention to detail. This can make the codebase difficult to maintain and update, leading to longer development cycles and increased costs. .IP \(bu 2 \fIUnreliable Code\fP: Code that ignores exceptions is often unreliable and can lead to unpredictable behavior. This can cause frustration for users and erode trust in the software. .UNINDENT .sp To avoid these issues, developers should always handle exceptions properly. This means either fixing the underlying issue that caused the exception or propagating the exception up the call stack to a higher\-level handler. If an exception is not important, it should still be logged or reported in some way so that it can be tracked and addressed later. .sp If the exception is something that can be handled locally, then it should be handled within the catch block. This could involve logging the exception or taking other appropriate action to ensure that the exception is not ignored. .sp Here is an example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C try { // Some code that can throw an exception } catch (const std::exception& ex) { // Properly handle the exception, e.g.: std::cerr << \(dqException caught: \(dq << ex.what() << std::endl; } .ft P .fi .UNINDENT .UNINDENT .sp If the exception cannot be handled locally and needs to be propagated up the call stack, it should be re\-thrown or new exception should be thrown. .sp Here is an example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C try { // Some code that can throw an exception } catch (const std::exception& ex) { // Re\-throw the exception throw; } .ft P .fi .UNINDENT .UNINDENT .sp In some cases, catching the exception at this level may not be necessary, and it may be appropriate to let the exception propagate up the call stack. This can be done simply by not using \fBtry/catch\fP block. .sp Here is an example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void function() { // Some code that can throw an exception } void callerFunction() { try { function(); } catch (const std::exception& ex) { // Handling exception on higher level std::cerr << \(dqException caught: \(dq << ex.what() << std::endl; } } .ft P .fi .UNINDENT .UNINDENT .sp Other potential solution to avoid empty catch statements is to modify the code to avoid throwing the exception in the first place. This can be achieved by using a different API, checking for error conditions beforehand, or handling errors in a different way that does not involve exceptions. By eliminating the need for try\-catch blocks, the code becomes simpler and less error\-prone. .sp Here is an example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Old code: try { mapContainer[\(dqKey\(dq].callFunction(); } catch(const std::out_of_range&) { } // New code if (auto it = mapContainer.find(\(dqKey\(dq); it != mapContainer.end()) { it\->second.callFunction(); } .ft P .fi .UNINDENT .UNINDENT .sp In conclusion, empty catch statements are a bad practice that can lead to hidden bugs, security issues, poor code quality, and unreliable code. By handling exceptions properly, developers can ensure that their code is robust, secure, and maintainable. .SS Options .INDENT 0.0 .TP .B IgnoreCatchWithKeywords This option can be used to ignore specific catch statements containing certain keywords. If a \fBcatch\fP statement body contains (case\-insensitive) any of the keywords listed in this semicolon\-separated option, then the catch will be ignored, and no warning will be raised. Default value: \fI@TODO;@FIXME\fP\&. .UNINDENT .INDENT 0.0 .TP .B AllowEmptyCatchForExceptions This option can be used to ignore empty catch statements for specific exception types. By default, the check will raise a warning if an empty catch statement is detected, regardless of the type of exception being caught. However, in certain situations, such as when a developer wants to intentionally ignore certain exceptions or handle them in a different way, it may be desirable to allow empty catch statements for specific exception types. To configure this option, a semicolon\-separated list of exception type names should be provided. If an exception type name in the list is caught in an empty catch statement, no warning will be raised. Default value: empty string. .UNINDENT .SS bugprone\-exception\-escape .sp Finds functions which may throw an exception directly or indirectly, but they should not. The functions which should not throw exceptions are the following: .INDENT 0.0 .IP \(bu 2 Destructors .IP \(bu 2 Move constructors .IP \(bu 2 Move assignment operators .IP \(bu 2 The \fBmain()\fP functions .IP \(bu 2 \fBswap()\fP functions .IP \(bu 2 Functions marked with \fBthrow()\fP or \fBnoexcept\fP .IP \(bu 2 Other functions given as option .UNINDENT .sp A destructor throwing an exception may result in undefined behavior, resource leaks or unexpected termination of the program. Throwing move constructor or move assignment also may result in undefined behavior or resource leak. The \fBswap()\fP operations expected to be non throwing most of the cases and they are always possible to implement in a non throwing way. Non throwing \fBswap()\fP operations are also used to create move operations. A throwing \fBmain()\fP function also results in unexpected termination. .sp Functions declared explicitly with \fBnoexcept(false)\fP or \fBthrow(exception)\fP will be excluded from the analysis, as even though it is not recommended for functions like \fBswap()\fP, \fBmain()\fP, move constructors, move assignment operators and destructors, it is a clear indication of the developer\(aqs intention and should be respected. .sp WARNING! This check may be expensive on large source files. .SS Options .INDENT 0.0 .TP .B FunctionsThatShouldNotThrow Comma separated list containing function names which should not throw. An example value for this parameter can be \fBWinMain\fP which adds function \fBWinMain()\fP in the Windows API to the list of the functions which should not throw. Default value is an empty string. .UNINDENT .INDENT 0.0 .TP .B IgnoredExceptions Comma separated list containing type names which are not counted as thrown exceptions in the check. Default value is an empty string. .UNINDENT .SS bugprone\-fold\-init\-type .sp The check flags type mismatches in \fI\%folds\fP like \fBstd::accumulate\fP that might result in loss of precision. \fBstd::accumulate\fP folds an input range into an initial value using the type of the latter, with \fBoperator+\fP by default. This can cause loss of precision through: .INDENT 0.0 .IP \(bu 2 Truncation: The following code uses a floating point range and an int initial value, so truncation will happen at every application of \fBoperator+\fP and the result will be \fI0\fP, which might not be what the user expected. .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C auto a = {0.5f, 0.5f, 0.5f, 0.5f}; return std::accumulate(std::begin(a), std::end(a), 0); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 Overflow: The following code also returns \fI0\fP\&. .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C auto a = {65536LL * 65536 * 65536}; return std::accumulate(std::begin(a), std::end(a), 0); .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-forward\-declaration\-namespace .sp Checks if an unused forward declaration is in a wrong namespace. .sp The check inspects all unused forward declarations and checks if there is any declaration/definition with the same name existing, which could indicate that the forward declaration is in a potentially wrong namespace. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C namespace na { struct A; } namespace nb { struct A {}; } nb::A a; // warning : no definition found for \(aqA\(aq, but a definition with the same name // \(aqA\(aq found in another namespace \(aqnb::\(aq .ft P .fi .UNINDENT .UNINDENT .sp This check can only generate warnings, but it can\(aqt suggest a fix at this point. .SS bugprone\-forwarding\-reference\-overload .sp The check looks for perfect forwarding constructors that can hide copy or move constructors. If a non const lvalue reference is passed to the constructor, the forwarding reference parameter will be a better match than the const reference parameter of the copy constructor, so the perfect forwarding constructor will be called, which can be confusing. For detailed description of this issue see: Scott Meyers, Effective Modern C++, Item 26. .sp Consider the following example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Person { public: // C1: perfect forwarding ctor template explicit Person(T&& n) {} // C2: perfect forwarding ctor with parameter default value template explicit Person(T&& n, int x = 1) {} // C3: perfect forwarding ctor guarded with enable_if template, void>> explicit Person(T&& n) {} // C4: variadic perfect forwarding ctor guarded with enable_if template, A&&...>, int> = 0> explicit Person(A&&... a) {} // C5: perfect forwarding ctor guarded with requires expression template requires requires { is_special; } explicit Person(T&& n) {} // C6: perfect forwarding ctor guarded with concept requirement template explicit Person(T&& n) {} // (possibly compiler generated) copy ctor Person(const Person& rhs); }; .ft P .fi .UNINDENT .UNINDENT .sp The check warns for constructors C1 and C2, because those can hide copy and move constructors. We suppress warnings if the copy and the move constructors are both disabled (deleted or private), because there is nothing the perfect forwarding constructor could hide in this case. We also suppress warnings for constructors like C3\-C6 that are guarded with an \fBenable_if\fP or a concept, assuming the programmer was aware of the possible hiding. .SS Background .sp For deciding whether a constructor is guarded with enable_if, we consider the types of the constructor parameters, the default values of template type parameters and the types of non\-type template parameters with a default literal value. If any part of these types is \fBstd::enable_if\fP or \fBstd::enable_if_t\fP, we assume the constructor is guarded. .SS bugprone\-implicit\-widening\-of\-multiplication\-result .sp The check diagnoses instances where a result of a multiplication is implicitly widened, and suggests (with fix\-it) to either silence the code by making widening explicit, or to perform the multiplication in a wider type, to avoid the widening afterwards. .sp This is mainly useful when operating on very large buffers. For example, consider: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void zeroinit(char* base, unsigned width, unsigned height) { for(unsigned row = 0; row != height; ++row) { for(unsigned col = 0; col != width; ++col) { char* ptr = base + row * width + col; *ptr = 0; } } } .ft P .fi .UNINDENT .UNINDENT .sp This is fine in general, but if \fBwidth * height\fP overflows, you end up wrapping back to the beginning of \fBbase\fP instead of processing the entire requested buffer. .sp Indeed, this only matters for pretty large buffers (4GB+), but that can happen very easily for example in image processing, where for that to happen you \(dqonly\(dq need a ~269MPix image. .SS Options .INDENT 0.0 .TP .B UseCXXStaticCastsInCppSources When suggesting fix\-its for C++ code, should C++\-style \fBstatic_cast<>()\fP\(aqs be suggested, or C\-style casts. Defaults to \fBtrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B UseCXXHeadersInCppSources When suggesting to include the appropriate header in C++ code, should \fB\fP header be suggested, or \fB\fP\&. Defaults to \fBtrue\fP\&. .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C long mul(int a, int b) { return a * b; // warning: performing an implicit widening conversion to type \(aqlong\(aq of a multiplication performed in type \(aqint\(aq } char* ptr_add(char *base, int a, int b) { return base + a * b; // warning: result of multiplication in type \(aqint\(aq is used as a pointer offset after an implicit widening conversion to type \(aqssize_t\(aq } char ptr_subscript(char *base, int a, int b) { return base[a * b]; // warning: result of multiplication in type \(aqint\(aq is used as a pointer offset after an implicit widening conversion to type \(aqssize_t\(aq } .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-inaccurate\-erase .sp Checks for inaccurate use of the \fBerase()\fP method. .sp Algorithms like \fBremove()\fP do not actually remove any element from the container but return an iterator to the first redundant element at the end of the container. These redundant elements must be removed using the \fBerase()\fP method. This check warns when not all of the elements will be removed due to using an inappropriate overload. .sp For example, the following code erases only one element: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector xs; \&... xs.erase(std::remove(xs.begin(), xs.end(), 10)); .ft P .fi .UNINDENT .UNINDENT .sp Call the two\-argument overload of \fBerase()\fP to remove the subrange: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector xs; \&... xs.erase(std::remove(xs.begin(), xs.end(), 10), xs.end()); .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-incorrect\-roundings .sp Checks the usage of patterns known to produce incorrect rounding. Programmers often use: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C (int)(double_expression + 0.5) .ft P .fi .UNINDENT .UNINDENT .sp to round the double expression to an integer. The problem with this: .INDENT 0.0 .IP 1. 3 It is unnecessarily slow. .IP 2. 3 It is incorrect. The number 0.499999975 (smallest representable float number below 0.5) rounds to 1.0. Even worse behavior for negative numbers where both \-0.5f and \-1.4f both round to 0.0. .UNINDENT .SS bugprone\-infinite\-loop .sp Finds obvious infinite loops (loops where the condition variable is not changed at all). .sp Finding infinite loops is well\-known to be impossible (halting problem). However, it is possible to detect some obvious infinite loops, for example, if the loop condition is not changed. This check detects such loops. A loop is considered infinite if it does not have any loop exit statement (\fBbreak\fP, \fBcontinue\fP, \fBgoto\fP, \fBreturn\fP, \fBthrow\fP or a call to a function called as \fB[[noreturn]]\fP) and all of the following conditions hold for every variable in the condition: .INDENT 0.0 .IP \(bu 2 It is a local variable. .IP \(bu 2 It has no reference or pointer aliases. .IP \(bu 2 It is not a structure or class member. .UNINDENT .sp Furthermore, the condition must not contain a function call to consider the loop infinite since functions may return different values for different calls. .sp For example, the following loop is considered infinite \fIi\fP is not changed in the body: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int i = 0, j = 0; while (i < 10) { ++j; } .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-integer\-division .sp Finds cases where integer division in a floating point context is likely to cause unintended loss of precision. .sp No reports are made if divisions are part of the following expressions: .INDENT 0.0 .IP \(bu 2 operands of operators expecting integral or bool types, .IP \(bu 2 call expressions of integral or bool types, and .IP \(bu 2 explicit cast expressions to integral or bool types, .UNINDENT .sp as these are interpreted as signs of deliberateness from the programmer. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C float floatFunc(float); int intFunc(int); double d; int i = 42; // Warn, floating\-point values expected. d = 32 * 8 / (2 + i); d = 8 * floatFunc(1 + 7 / 2); d = i / (1 << 4); // OK, no integer division. d = 32 * 8.0 / (2 + i); d = 8 * floatFunc(1 + 7.0 / 2); d = (double)i / (1 << 4); // OK, there are signs of deliberateness. d = 1 << (i / 2); d = 9 + intFunc(6 * i / 32); d = (int)(i / 32) \- 8; .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-lambda\-function\-name .sp Checks for attempts to get the name of a function from within a lambda expression. The name of a lambda is always something like \fBoperator()\fP, which is almost never what was intended. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void FancyFunction() { [] { printf(\(dqCalled from %s\en\(dq, __func__); }(); [] { printf(\(dqNow called from %s\en\(dq, __FUNCTION__); }(); } .ft P .fi .UNINDENT .UNINDENT .sp Output: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C Called from operator() Now called from operator() .ft P .fi .UNINDENT .UNINDENT .sp Likely intended output: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C Called from FancyFunction Now called from FancyFunction .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-macro\-parentheses .sp Finds macros that can have unexpected behavior due to missing parentheses. .sp Macros are expanded by the preprocessor as\-is. As a result, there can be unexpected behavior; operators may be evaluated in unexpected order and unary operators may become binary operators, etc. .sp When the replacement list has an expression, it is recommended to surround it with parentheses. This ensures that the macro result is evaluated completely before it is used. .sp It is also recommended to surround macro arguments in the replacement list with parentheses. This ensures that the argument value is calculated properly. .SS bugprone\-macro\-repeated\-side\-effects .sp Checks for repeated argument with side effects in macros. .SS bugprone\-misplaced\-operator\-in\-strlen\-in\-alloc .sp Finds cases where \fB1\fP is added to the string in the argument to \fBstrlen()\fP, \fBstrnlen()\fP, \fBstrnlen_s()\fP, \fBwcslen()\fP, \fBwcsnlen()\fP, and \fBwcsnlen_s()\fP instead of the result and the value is used as an argument to a memory allocation function (\fBmalloc()\fP, \fBcalloc()\fP, \fBrealloc()\fP, \fBalloca()\fP) or the \fBnew[]\fP operator in \fIC++\fP\&. The check detects error cases even if one of these functions (except the \fBnew[]\fP operator) is called by a constant function pointer. Cases where \fB1\fP is added both to the parameter and the result of the \fBstrlen()\fP\-like function are ignored, as are cases where the whole addition is surrounded by extra parentheses. .sp \fIC\fP example code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void bad_malloc(char *str) { char *c = (char*) malloc(strlen(str + 1)); } .ft P .fi .UNINDENT .UNINDENT .sp The suggested fix is to add \fB1\fP to the return value of \fBstrlen()\fP and not to its argument. In the example above the fix would be .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C char *c = (char*) malloc(strlen(str) + 1); .ft P .fi .UNINDENT .UNINDENT .sp \fIC++\fP example code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void bad_new(char *str) { char *c = new char[strlen(str + 1)]; } .ft P .fi .UNINDENT .UNINDENT .sp As in the \fIC\fP code with the \fBmalloc()\fP function, the suggested fix is to add \fB1\fP to the return value of \fBstrlen()\fP and not to its argument. In the example above the fix would be .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C char *c = new char[strlen(str) + 1]; .ft P .fi .UNINDENT .UNINDENT .sp Example for silencing the diagnostic: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void bad_malloc(char *str) { char *c = (char*) malloc(strlen((str + 1))); } .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-misplaced\-pointer\-arithmetic\-in\-alloc .sp Finds cases where an integer expression is added to or subtracted from the result of a memory allocation function (\fBmalloc()\fP, \fBcalloc()\fP, \fBrealloc()\fP, \fBalloca()\fP) instead of its argument. The check detects error cases even if one of these functions is called by a constant function pointer. .sp Example code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void bad_malloc(int n) { char *p = (char*) malloc(n) + 10; } .ft P .fi .UNINDENT .UNINDENT .sp The suggested fix is to add the integer expression to the argument of \fBmalloc\fP and not to its result. In the example above the fix would be .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C char *p = (char*) malloc(n + 10); .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-misplaced\-widening\-cast .sp This check will warn when there is a cast of a calculation result to a bigger type. If the intention of the cast is to avoid loss of precision then the cast is misplaced, and there can be loss of precision. Otherwise the cast is ineffective. .sp Example code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C long f(int x) { return (long)(x * 1000); } .ft P .fi .UNINDENT .UNINDENT .sp The result \fBx * 1000\fP is first calculated using \fBint\fP precision. If the result exceeds \fBint\fP precision there is loss of precision. Then the result is casted to \fBlong\fP\&. .sp If there is no loss of precision then the cast can be removed or you can explicitly cast to \fBint\fP instead. .sp If you want to avoid loss of precision then put the cast in a proper location, for instance: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C long f(int x) { return (long)x * 1000; } .ft P .fi .UNINDENT .UNINDENT .SS Implicit casts .sp Forgetting to place the cast at all is at least as dangerous and at least as common as misplacing it. If \fI\%CheckImplicitCasts\fP is enabled the check also detects these cases, for instance: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C long f(int x) { return x * 1000; } .ft P .fi .UNINDENT .UNINDENT .SS Floating point .sp Currently warnings are only written for integer conversion. No warning is written for this code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C double f(float x) { return (double)(x * 10.0f); } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B CheckImplicitCasts If \fItrue\fP, enables detection of implicit casts. Default is \fIfalse\fP\&. .UNINDENT .SS bugprone\-move\-forwarding\-reference .sp Warns if \fBstd::move\fP is called on a forwarding reference, for example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C template void foo(T&& t) { bar(std::move(t)); } .ft P .fi .UNINDENT .UNINDENT .sp \fI\%Forwarding references\fP should typically be passed to \fBstd::forward\fP instead of \fBstd::move\fP, and this is the fix that will be suggested. .sp (A forwarding reference is an rvalue reference of a type that is a deduced function template argument.) .sp In this example, the suggested fix would be .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bar(std::forward(t)); .ft P .fi .UNINDENT .UNINDENT .SS Background .sp Code like the example above is sometimes written with the expectation that \fBT&&\fP will always end up being an rvalue reference, no matter what type is deduced for \fBT\fP, and that it is therefore not possible to pass an lvalue to \fBfoo()\fP\&. However, this is not true. Consider this example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string s = \(dqHello, world\(dq; foo(s); .ft P .fi .UNINDENT .UNINDENT .sp This code compiles and, after the call to \fBfoo()\fP, \fBs\fP is left in an indeterminate state because it has been moved from. This may be surprising to the caller of \fBfoo()\fP because no \fBstd::move\fP was used when calling \fBfoo()\fP\&. .sp The reason for this behavior lies in the special rule for template argument deduction on function templates like \fBfoo()\fP \-\- i.e. on function templates that take an rvalue reference argument of a type that is a deduced function template argument. (See section [temp.deduct.call]/3 in the C++11 standard.) .sp If \fBfoo()\fP is called on an lvalue (as in the example above), then \fBT\fP is deduced to be an lvalue reference. In the example, \fBT\fP is deduced to be \fBstd::string &\fP\&. The type of the argument \fBt\fP therefore becomes \fBstd::string& &&\fP; by the reference collapsing rules, this collapses to \fBstd::string&\fP\&. .sp This means that the \fBfoo(s)\fP call passes \fBs\fP as an lvalue reference, and \fBfoo()\fP ends up moving \fBs\fP and thereby placing it into an indeterminate state. .SS bugprone\-multiple\-new\-in\-one\-expression .sp Finds multiple \fBnew\fP operator calls in a single expression, where the allocated memory by the first \fBnew\fP may leak if the second allocation fails and throws exception. .sp C++ does often not specify the exact order of evaluation of the operands of an operator or arguments of a function. Therefore if a first allocation succeeds and a second fails, in an exception handler it is not possible to tell which allocation has failed and free the memory. Even if the order is fixed the result of a first \fBnew\fP may be stored in a temporary location that is not reachable at the time when a second allocation fails. It is best to avoid any expression that contains more than one \fBoperator new\fP call, if exception handling is used to check for allocation errors. .sp Different rules apply for are the short\-circuit operators \fB||\fP and \fB&&\fP and the \fB,\fP operator, where evaluation of one side must be completed before the other starts. Expressions of a list\-initialization (initialization or construction using \fB{\fP and \fB}\fP characters) are evaluated in fixed order. Similarly, condition of a \fB?\fP operator is evaluated before the branches are evaluated. .sp The check reports warning if two \fBnew\fP calls appear in one expression at different sides of an operator, or if \fBnew\fP calls appear in different arguments of a function call (that can be an object construction with \fB()\fP syntax). These \fBnew\fP calls can be nested at any level. For any warning to be emitted the \fBnew\fP calls should be in a code block where exception handling is used with catch for \fBstd::bad_alloc\fP or \fBstd::exception\fP\&. At \fB||\fP, \fB&&\fP, \fB,\fP, \fB?\fP (condition and one branch) operators no warning is emitted. No warning is emitted if both of the memory allocations are not assigned to a variable or not passed directly to a function. The reason is that in this case the memory may be intentionally not freed or the allocated objects can be self\-destructing objects. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct A { int Var; }; struct B { B(); B(A *); int Var; }; struct C { int *X1; int *X2; }; void f(A *, B *); int f1(A *); int f1(B *); bool f2(A *); void foo() { A *PtrA; B *PtrB; try { // Allocation of \(aqB\(aq/\(aqA\(aq may fail after memory for \(aqA\(aq/\(aqB\(aq was allocated. f(new A, new B); // warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception; order of these allocations is undefined // List (aggregate) initialization is used. C C1{new int, new int}; // no warning // Allocation of \(aqB\(aq/\(aqA\(aq may fail after memory for \(aqA\(aq/\(aqB\(aq was allocated but not yet passed to function \(aqf1\(aq. int X = f1(new A) + f1(new B); // warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception; order of these allocations is undefined // Allocation of \(aqB\(aq may fail after memory for \(aqA\(aq was allocated. // From C++17 on memory for \(aqB\(aq is allocated first but still may leak if allocation of \(aqA\(aq fails. PtrB = new B(new A); // warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception // \(aqnew A\(aq and \(aqnew B\(aq may be performed in any order. // \(aqnew B\(aq/\(aqnew A\(aq may fail after memory for \(aqA\(aq/\(aqB\(aq was allocated but not assigned to \(aqPtrA\(aq/\(aqPtrB\(aq. (PtrA = new A)\->Var = (PtrB = new B)\->Var; // warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception; order of these allocations is undefined // Evaluation of \(aqf2(new A)\(aq must be finished before \(aqf1(new B)\(aq starts. // If \(aqnew B\(aq fails the allocated memory for \(aqA\(aq is supposedly handled correctly because function \(aqf2\(aq could take the ownership. bool Z = f2(new A) || f1(new B); // no warning X = (f2(new A) ? f1(new A) : f1(new B)); // no warning // No warning if the result of both allocations is not passed to a function // or stored in a variable. (new A)\->Var = (new B)\->Var; // no warning // No warning if at least one non\-throwing allocation is used. f(new(std::nothrow) A, new B); // no warning } catch(std::bad_alloc) { } // No warning if the allocation is outside a try block (or no catch handler exists for std::bad_alloc). // (The fact if exceptions can escape from \(aqfoo\(aq is not taken into account.) f(new A, new B); // no warning } .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-multiple\-statement\-macro .sp Detect multiple statement macros that are used in unbraced conditionals. Only the first statement of the macro will be inside the conditional and the other ones will be executed unconditionally. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #define INCREMENT_TWO(x, y) (x)++; (y)++ if (do_increment) INCREMENT_TWO(a, b); // (b)++ will be executed unconditionally. .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-narrowing\-conversions .sp The bugprone\-narrowing\-conversions check is an alias, please see \fI\%cppcoreguidelines\-narrowing\-conversions\fP for more information. .SS bugprone\-no\-escape .sp Finds pointers with the \fBnoescape\fP attribute that are captured by an asynchronously\-executed block. The block arguments in \fBdispatch_async()\fP and \fBdispatch_after()\fP are guaranteed to escape, so it is an error if a pointer with the \fBnoescape\fP attribute is captured by one of these blocks. .sp The following is an example of an invalid use of the \fBnoescape\fP attribute. .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(__attribute__((noescape)) int *p) { dispatch_async(queue, ^{ *p = 123; }); }); .ft P .fi .UNINDENT .UNINDENT .UNINDENT .UNINDENT .SS bugprone\-non\-zero\-enum\-to\-bool\-conversion .sp Detect implicit and explicit casts of \fBenum\fP type into \fBbool\fP where \fBenum\fP type doesn\(aqt have a zero\-value enumerator. If the \fBenum\fP is used only to hold values equal to its enumerators, then conversion to \fBbool\fP will always result in \fBtrue\fP value. This can lead to unnecessary code that reduces readability and maintainability and can result in bugs. .sp May produce false positives if the \fBenum\fP is used to store other values (used as a bit\-mask or zero\-initialized on purpose). To deal with them, \fB// NOLINT\fP or casting first to the underlying type before casting to \fBbool\fP can be used. .sp It is important to note that this check will not generate warnings if the definition of the enumeration type is not available. Additionally, C++11 enumeration classes are supported by this check. .sp Overall, this check serves to improve code quality and readability by identifying and flagging instances where implicit or explicit casts from enumeration types to boolean could cause potential issues. .SS Example .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C enum EStatus { OK = 1, NOT_OK, UNKNOWN }; void process(EStatus status) { if (!status) { // this true\-branch won\(aqt be executed return; } // proceed with \(dqvalid data\(dq } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B EnumIgnoreList Option is used to ignore certain enum types when checking for implicit/explicit casts to bool. It accepts a semicolon\-separated list of (fully qualified) enum type names or regular expressions that match the enum type names. The default value is an empty string, which means no enums will be ignored. .UNINDENT .SS bugprone\-not\-null\-terminated\-result .sp Finds function calls where it is possible to cause a not null\-terminated result. Usually the proper length of a string is \fBstrlen(src) + 1\fP or equal length of this expression, because the null terminator needs an extra space. Without the null terminator it can result in undefined behavior when the string is read. .sp The following and their respective \fBwchar_t\fP based functions are checked: .sp \fBmemcpy\fP, \fBmemcpy_s\fP, \fBmemchr\fP, \fBmemmove\fP, \fBmemmove_s\fP, \fBstrerror_s\fP, \fBstrncmp\fP, \fBstrxfrm\fP .sp The following is a real\-world example where the programmer forgot to increase the passed third argument, which is \fBsize_t length\fP\&. That is why the length of the allocated memory is not enough to hold the null terminator. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static char *stringCpy(const std::string &str) { char *result = reinterpret_cast(malloc(str.size())); memcpy(result, str.data(), str.size()); return result; } .ft P .fi .UNINDENT .UNINDENT .sp In addition to issuing warnings, fix\-it rewrites all the necessary code. It also tries to adjust the capacity of the destination array: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static char *stringCpy(const std::string &str) { char *result = reinterpret_cast(malloc(str.size() + 1)); strcpy(result, str.data()); return result; } .ft P .fi .UNINDENT .UNINDENT .sp Note: It cannot guarantee to rewrite every of the path\-sensitive memory allocations. .SS Transformation rules of \(aqmemcpy()\(aq .sp It is possible to rewrite the \fBmemcpy()\fP and \fBmemcpy_s()\fP calls as the following four functions: \fBstrcpy()\fP, \fBstrncpy()\fP, \fBstrcpy_s()\fP, \fBstrncpy_s()\fP, where the latter two are the safer versions of the former two. It rewrites the \fBwchar_t\fP based memory handler functions respectively. .SS Rewrite based on the destination array .INDENT 0.0 .IP \(bu 2 If copy to the destination array cannot overflow [1] the new function should be the older copy function (ending with \fBcpy\fP), because it is more efficient than the safe version. .IP \(bu 2 If copy to the destination array can overflow [1] and \fI\%WantToUseSafeFunctions\fP is set to \fItrue\fP and it is possible to obtain the capacity of the destination array then the new function could be the safe version (ending with \fBcpy_s\fP). .IP \(bu 2 If the new function is could be safe version and C++ files are analyzed and the destination array is plain \fBchar\fP/\fBwchar_t\fP without \fBun/signed\fP then the length of the destination array can be omitted. .IP \(bu 2 If the new function is could be safe version and the destination array is \fBun/signed\fP it needs to be casted to plain \fBchar *\fP/\fBwchar_t *\fP\&. .UNINDENT .INDENT 0.0 .TP .B [1] It is possible to overflow: .INDENT 7.0 .IP \(bu 2 If the capacity of the destination array is unknown. .IP \(bu 2 If the given length is equal to the destination array\(aqs capacity. .UNINDENT .UNINDENT .SS Rewrite based on the length of the source string .INDENT 0.0 .IP \(bu 2 If the given length is \fBstrlen(source)\fP or equal length of this expression then the new function should be the older copy function (ending with \fBcpy\fP), as it is more efficient than the safe version (ending with \fBcpy_s\fP). .IP \(bu 2 Otherwise we assume that the programmer wanted to copy \(aqN\(aq characters, so the new function is \fBncpy\fP\-like which copies \(aqN\(aq characters. .UNINDENT .SS Transformations with \(aqstrlen()\(aq or equal length of this expression .sp It transforms the \fBwchar_t\fP based memory and string handler functions respectively (where only \fBstrerror_s\fP does not have \fBwchar_t\fP based alias). .SS Memory handler functions .sp \fBmemcpy\fP Please visit the \fI\%Transformation rules of \(aqmemcpy()\(aq\fP section. .sp \fBmemchr\fP Usually there is a C\-style cast and it is needed to be removed, because the new function \fBstrchr\fP\(aqs return type is correct. The given length is going to be removed. .sp \fBmemmove\fP If safe functions are available the new function is \fBmemmove_s\fP, which has a new second argument which is the length of the destination array, it is adjusted, and the length of the source string is incremented by one. If safe functions are not available the given length is incremented by one. .sp \fBmemmove_s\fP The given length is incremented by one. .SS String handler functions .sp \fBstrerror_s\fP The given length is incremented by one. .sp \fBstrncmp\fP If the third argument is the first or the second argument\(aqs \fBlength + 1\fP it has to be truncated without the \fB+ 1\fP operation. .sp \fBstrxfrm\fP The given length is incremented by one. .SS Options .INDENT 0.0 .TP .B WantToUseSafeFunctions The value \fItrue\fP specifies that the target environment is considered to implement \(aq_s\(aq suffixed memory and string handler functions which are safer than older versions (e.g. \(aqmemcpy_s()\(aq). The default value is \fItrue\fP\&. .UNINDENT .SS bugprone\-parent\-virtual\-call .sp Detects and fixes calls to grand\-...parent virtual methods instead of calls to overridden parent\(aqs virtual methods. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct A { int virtual foo() {...} }; struct B: public A { int foo() override {...} }; struct C: public B { int foo() override { A::foo(); } // ^^^^^^^^ // warning: qualified name A::foo refers to a member overridden in subclass; did you mean \(aqB\(aq? [bugprone\-parent\-virtual\-call] }; .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-posix\-return .sp Checks if any calls to \fBpthread_*\fP or \fBposix_*\fP functions (except \fBposix_openpt\fP) expect negative return values. These functions return either \fB0\fP on success or an \fBerrno\fP on failure, which is positive only. .sp Example buggy usage looks like: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (posix_fadvise(...) < 0) { .ft P .fi .UNINDENT .UNINDENT .sp This will never happen as the return value is always non\-negative. A simple fix could be: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (posix_fadvise(...) > 0) { .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-redundant\-branch\-condition .sp Finds condition variables in nested \fBif\fP statements that were also checked in the outer \fBif\fP statement and were not changed. .sp Simple example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bool onFire = isBurning(); if (onFire) { if (onFire) scream(); } .ft P .fi .UNINDENT .UNINDENT .sp Here \fIonFire\fP is checked both in the outer \fBif\fP and the inner \fBif\fP statement without a possible change between the two checks. The check warns for this code and suggests removal of the second checking of variable \fIonFire\fP\&. .sp The checker also detects redundant condition checks if the condition variable is an operand of a logical \(dqand\(dq (\fB&&\fP) or a logical \(dqor\(dq (\fB||\fP) operator: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bool onFire = isBurning(); if (onFire) { if (onFire && peopleInTheBuilding > 0) scream(); } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bool onFire = isBurning(); if (onFire) { if (onFire || isCollapsing()) scream(); } .ft P .fi .UNINDENT .UNINDENT .sp In the first case (logical \(dqand\(dq) the suggested fix is to remove the redundant condition variable and keep the other side of the \fB&&\fP\&. In the second case (logical \(dqor\(dq) the whole \fBif\fP is removed similarly to the simple case on the top. .sp The condition of the outer \fBif\fP statement may also be a logical \(dqand\(dq (\fB&&\fP) expression: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bool onFire = isBurning(); if (onFire && fireFighters < 10) { if (someOtherCondition()) { if (onFire) scream(); } } .ft P .fi .UNINDENT .UNINDENT .sp The error is also detected if both the outer statement is a logical \(dqand\(dq (\fB&&\fP) and the inner statement is a logical \(dqand\(dq (\fB&&\fP) or \(dqor\(dq (\fB||\fP). The inner \fBif\fP statement does not have to be a direct descendant of the outer one. .sp No error is detected if the condition variable may have been changed between the two checks: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bool onFire = isBurning(); if (onFire) { tryToExtinguish(onFire); if (onFire && peopleInTheBuilding > 0) scream(); } .ft P .fi .UNINDENT .UNINDENT .sp Every possible change is considered, thus if the condition variable is not a local variable of the function, it is a volatile or it has an alias (pointer or reference) then no warning is issued. .SS Known limitations .sp The \fBelse\fP branch is not checked currently for negated condition variable: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bool onFire = isBurning(); if (onFire) { scream(); } else { if (!onFire) { continueWork(); } } .ft P .fi .UNINDENT .UNINDENT .sp The checker currently only detects redundant checking of single condition variables. More complex expressions are not checked: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (peopleInTheBuilding == 1) { if (peopleInTheBuilding == 1) { doSomething(); } } .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-reserved\-identifier .sp \fIcert\-dcl37\-c\fP and \fIcert\-dcl51\-cpp\fP redirect here as an alias for this check. .sp Checks for usages of identifiers reserved for use by the implementation. .sp The C and C++ standards both reserve the following names for such use: .INDENT 0.0 .IP \(bu 2 identifiers that begin with an underscore followed by an uppercase letter; .IP \(bu 2 identifiers in the global namespace that begin with an underscore. .UNINDENT .sp The C standard additionally reserves names beginning with a double underscore, while the C++ standard strengthens this to reserve names with a double underscore occurring anywhere. .sp Violating the naming rules above results in undefined behavior. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C namespace NS { void __f(); // name is not allowed in user code using _Int = int; // same with this #define cool__macro // also this } int _g(); // disallowed in global namespace only .ft P .fi .UNINDENT .UNINDENT .sp The check can also be inverted, i.e. it can be configured to flag any identifier that is _not_ a reserved identifier. This mode is for use by e.g. standard library implementors, to ensure they don\(aqt infringe on the user namespace. .sp This check does not (yet) check for other reserved names, e.g. macro names identical to language keywords, and names specifically reserved by language standards, e.g. C++ \(aqzombie names\(aq and C future library directions. .sp This check corresponds to CERT C Coding Standard rule \fI\%DCL37\-C. Do not declare or define a reserved identifier\fP as well as its C++ counterpart, \fI\%DCL51\-CPP. Do not declare or define a reserved identifier\fP\&. .SS Options .INDENT 0.0 .TP .B Invert If \fItrue\fP, inverts the check, i.e. flags names that are not reserved. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B AllowedIdentifiers Semicolon\-separated list of regular expressions that the check ignores. Default is an empty list. .UNINDENT .SS bugprone\-shared\-ptr\-array\-mismatch .sp Finds initializations of C++ shared pointers to non\-array type that are initialized with an array. .sp If a shared pointer \fBstd::shared_ptr\fP is initialized with a new\-expression \fBnew T[]\fP the memory is not deallocated correctly. The pointer uses plain \fBdelete\fP in this case to deallocate the target memory. Instead a \fBdelete[]\fP call is needed. A \fBstd::shared_ptr\fP calls the correct delete operator. .sp The check offers replacement of \fBshared_ptr\fP to \fBshared_ptr\fP if it is used at a single variable declaration (one variable in one statement). .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::shared_ptr x(new Foo[10]); // \-> std::shared_ptr x(new Foo[10]); // ^ warning: shared pointer to non\-array is initialized with array [bugprone\-shared\-ptr\-array\-mismatch] std::shared_ptr x1(new Foo), x2(new Foo[10]); // no replacement // ^ warning: shared pointer to non\-array is initialized with array [bugprone\-shared\-ptr\-array\-mismatch] std::shared_ptr x3(new Foo[10], [](const Foo *ptr) { delete[] ptr; }); // no warning struct S { std::shared_ptr x(new Foo[10]); // no replacement in this case // ^ warning: shared pointer to non\-array is initialized with array [bugprone\-shared\-ptr\-array\-mismatch] }; .ft P .fi .UNINDENT .UNINDENT .sp This check partially covers the CERT C++ Coding Standard rule \fI\%MEM51\-CPP. Properly deallocate dynamically allocated resources\fP However, only the \fBstd::shared_ptr\fP case is detected by this check. .SS bugprone\-signal\-handler .sp Finds specific constructs in signal handler functions that can cause undefined behavior. The rules for what is allowed differ between C++ language versions. .sp Checked signal handler rules for C: .INDENT 0.0 .IP \(bu 2 Calls to non\-asynchronous\-safe functions are not allowed. .UNINDENT .sp Checked signal handler rules for up to and including C++14: .INDENT 0.0 .IP \(bu 2 Calls to non\-asynchronous\-safe functions are not allowed. .IP \(bu 2 C++\-specific code constructs are not allowed in signal handlers. In other words, only the common subset of C and C++ is allowed to be used. .IP \(bu 2 Calls to functions with non\-C linkage are not allowed (including the signal handler itself). .UNINDENT .sp The check is disabled on C++17 and later. .sp Asynchronous\-safety is determined by comparing the function\(aqs name against a set of known functions. In addition, the function must come from a system header include and in a global namespace. The (possible) arguments passed to the function are not checked. Any function that cannot be determined to be asynchronous\-safe is assumed to be non\-asynchronous\-safe by the check, including user functions for which only the declaration is visible. Calls to user\-defined functions with visible definitions are checked recursively. .sp This check implements the CERT C Coding Standard rule \fI\%SIG30\-C. Call only asynchronous\-safe functions within signal handlers\fP and the rule \fI\%MSC54\-CPP. A signal handler must be a plain old function\fP\&. It has the alias names \fBcert\-sig30\-c\fP and \fBcert\-msc54\-cpp\fP\&. .SS Options .INDENT 0.0 .TP .B AsyncSafeFunctionSet Selects which set of functions is considered as asynchronous\-safe (and therefore allowed in signal handlers). It can be set to the following values: .INDENT 7.0 .TP .B \fBminimal\fP Selects a minimal set that is defined in the CERT SIG30\-C rule. and includes functions \fBabort()\fP, \fB_Exit()\fP, \fBquick_exit()\fP and \fBsignal()\fP\&. .TP .B \fBPOSIX\fP Selects a larger set of functions that is listed in POSIX.1\-2017 (see \fI\%this link\fP for more information). The following functions are included: \fB_Exit\fP, \fB_exit\fP, \fBabort\fP, \fBaccept\fP, \fBaccess\fP, \fBaio_error\fP, \fBaio_return\fP, \fBaio_suspend\fP, \fBalarm\fP, \fBbind\fP, \fBcfgetispeed\fP, \fBcfgetospeed\fP, \fBcfsetispeed\fP, \fBcfsetospeed\fP, \fBchdir\fP, \fBchmod\fP, \fBchown\fP, \fBclock_gettime\fP, \fBclose\fP, \fBconnect\fP, \fBcreat\fP, \fBdup\fP, \fBdup2\fP, \fBexecl\fP, \fBexecle\fP, \fBexecv\fP, \fBexecve\fP, \fBfaccessat\fP, \fBfchdir\fP, \fBfchmod\fP, \fBfchmodat\fP, \fBfchown\fP, \fBfchownat\fP, \fBfcntl\fP, \fBfdatasync\fP, \fBfexecve\fP, \fBffs\fP, \fBfork\fP, \fBfstat\fP, \fBfstatat\fP, \fBfsync\fP, \fBftruncate\fP, \fBfutimens\fP, \fBgetegid\fP, \fBgeteuid\fP, \fBgetgid\fP, \fBgetgroups\fP, \fBgetpeername\fP, \fBgetpgrp\fP, \fBgetpid\fP, \fBgetppid\fP, \fBgetsockname\fP, \fBgetsockopt\fP, \fBgetuid\fP, \fBhtonl\fP, \fBhtons\fP, \fBkill\fP, \fBlink\fP, \fBlinkat\fP, \fBlisten\fP, \fBlongjmp\fP, \fBlseek\fP, \fBlstat\fP, \fBmemccpy\fP, \fBmemchr\fP, \fBmemcmp\fP, \fBmemcpy\fP, \fBmemmove\fP, \fBmemset\fP, \fBmkdir\fP, \fBmkdirat\fP, \fBmkfifo\fP, \fBmkfifoat\fP, \fBmknod\fP, \fBmknodat\fP, \fBntohl\fP, \fBntohs\fP, \fBopen\fP, \fBopenat\fP, \fBpause\fP, \fBpipe\fP, \fBpoll\fP, \fBposix_trace_event\fP, \fBpselect\fP, \fBpthread_kill\fP, \fBpthread_self\fP, \fBpthread_sigmask\fP, \fBquick_exit\fP, \fBraise\fP, \fBread\fP, \fBreadlink\fP, \fBreadlinkat\fP, \fBrecv\fP, \fBrecvfrom\fP, \fBrecvmsg\fP, \fBrename\fP, \fBrenameat\fP, \fBrmdir\fP, \fBselect\fP, \fBsem_post\fP, \fBsend\fP, \fBsendmsg\fP, \fBsendto\fP, \fBsetgid\fP, \fBsetpgid\fP, \fBsetsid\fP, \fBsetsockopt\fP, \fBsetuid\fP, \fBshutdown\fP, \fBsigaction\fP, \fBsigaddset\fP, \fBsigdelset\fP, \fBsigemptyset\fP, \fBsigfillset\fP, \fBsigismember\fP, \fBsiglongjmp\fP, \fBsignal\fP, \fBsigpause\fP, \fBsigpending\fP, \fBsigprocmask\fP, \fBsigqueue\fP, \fBsigset\fP, \fBsigsuspend\fP, \fBsleep\fP, \fBsockatmark\fP, \fBsocket\fP, \fBsocketpair\fP, \fBstat\fP, \fBstpcpy\fP, \fBstpncpy\fP, \fBstrcat\fP, \fBstrchr\fP, \fBstrcmp\fP, \fBstrcpy\fP, \fBstrcspn\fP, \fBstrlen\fP, \fBstrncat\fP, \fBstrncmp\fP, \fBstrncpy\fP, \fBstrnlen\fP, \fBstrpbrk\fP, \fBstrrchr\fP, \fBstrspn\fP, \fBstrstr\fP, \fBstrtok_r\fP, \fBsymlink\fP, \fBsymlinkat\fP, \fBtcdrain\fP, \fBtcflow\fP, \fBtcflush\fP, \fBtcgetattr\fP, \fBtcgetpgrp\fP, \fBtcsendbreak\fP, \fBtcsetattr\fP, \fBtcsetpgrp\fP, \fBtime\fP, \fBtimer_getoverrun\fP, \fBtimer_gettime\fP, \fBtimer_settime\fP, \fBtimes\fP, \fBumask\fP, \fBuname\fP, \fBunlink\fP, \fBunlinkat\fP, \fButime\fP, \fButimensat\fP, \fButimes\fP, \fBwait\fP, \fBwaitpid\fP, \fBwcpcpy\fP, \fBwcpncpy\fP, \fBwcscat\fP, \fBwcschr\fP, \fBwcscmp\fP, \fBwcscpy\fP, \fBwcscspn\fP, \fBwcslen\fP, \fBwcsncat\fP, \fBwcsncmp\fP, \fBwcsncpy\fP, \fBwcsnlen\fP, \fBwcspbrk\fP, \fBwcsrchr\fP, \fBwcsspn\fP, \fBwcsstr\fP, \fBwcstok\fP, \fBwmemchr\fP, \fBwmemcmp\fP, \fBwmemcpy\fP, \fBwmemmove\fP, \fBwmemset\fP, \fBwrite\fP .sp The function \fBquick_exit\fP is not included in the POSIX list but it is included here in the set of safe functions. .UNINDENT .sp The default value is \fBPOSIX\fP\&. .UNINDENT .SS bugprone\-signed\-char\-misuse .sp \fIcert\-str34\-c\fP redirects here as an alias for this check. For the CERT alias, the \fIDiagnoseSignedUnsignedCharComparisons\fP option is set to \fIfalse\fP\&. .sp Finds those \fBsigned char\fP \-> integer conversions which might indicate a programming error. The basic problem with the \fBsigned char\fP, that it might store the non\-ASCII characters as negative values. This behavior can cause a misunderstanding of the written code both when an explicit and when an implicit conversion happens. .sp When the code contains an explicit \fBsigned char\fP \-> integer conversion, the human programmer probably expects that the converted value matches with the character code (a value from [0..255]), however, the actual value is in [\-128..127] interval. To avoid this kind of misinterpretation, the desired way of converting from a \fBsigned char\fP to an integer value is converting to \fBunsigned char\fP first, which stores all the characters in the positive [0..255] interval which matches the known character codes. .sp In case of implicit conversion, the programmer might not actually be aware that a conversion happened and char value is used as an integer. There are some use cases when this unawareness might lead to a functionally imperfect code. For example, checking the equality of a \fBsigned char\fP and an \fBunsigned char\fP variable is something we should avoid in C++ code. During this comparison, the two variables are converted to integers which have different value ranges. For \fBsigned char\fP, the non\-ASCII characters are stored as a value in [\-128..\-1] interval, while the same characters are stored in the [128..255] interval for an \fBunsigned char\fP\&. .sp It depends on the actual platform whether plain \fBchar\fP is handled as \fBsigned char\fP by default and so it is caught by this check or not. To change the default behavior you can use \fB\-funsigned\-char\fP and \fB\-fsigned\-char\fP compilation options. .sp Currently, this check warns in the following cases: \- \fBsigned char\fP is assigned to an integer variable \- \fBsigned char\fP and \fBunsigned char\fP are compared with equality/inequality operator \- \fBsigned char\fP is converted to an integer in the array subscript .sp See also: \fI\%STR34\-C. Cast characters to unsigned char before converting to larger integer sizes\fP .sp A good example from the CERT description when a \fBchar\fP variable is used to read from a file that might contain non\-ASCII characters. The problem comes up when the code uses the \fB\-1\fP integer value as EOF, while the 255 character code is also stored as \fB\-1\fP in two\(aqs complement form of char type. See a simple example of this below. This code stops not only when it reaches the end of the file, but also when it gets a character with the 255 code. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #define EOF (\-1) int read(void) { char CChar; int IChar = EOF; if (readChar(CChar)) { IChar = CChar; } return IChar; } .ft P .fi .UNINDENT .UNINDENT .sp A proper way to fix the code above is converting the \fBchar\fP variable to an \fBunsigned char\fP value first. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #define EOF (\-1) int read(void) { char CChar; int IChar = EOF; if (readChar(CChar)) { IChar = static_cast(CChar); } return IChar; } .ft P .fi .UNINDENT .UNINDENT .sp Another use case is checking the equality of two \fBchar\fP variables with different signedness. Inside the non\-ASCII value range this comparison between a \fBsigned char\fP and an \fBunsigned char\fP always returns \fBfalse\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bool compare(signed char SChar, unsigned char USChar) { if (SChar == USChar) return true; return false; } .ft P .fi .UNINDENT .UNINDENT .sp The easiest way to fix this kind of comparison is casting one of the arguments, so both arguments will have the same type. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bool compare(signed char SChar, unsigned char USChar) { if (static_cast(SChar) == USChar) return true; return false; } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CharTypdefsToIgnore A semicolon\-separated list of typedef names. In this list, we can list typedefs for \fBchar\fP or \fBsigned char\fP, which will be ignored by the check. This is useful when a typedef introduces an integer alias like \fBsal_Int8\fP or \fBint8_t\fP\&. In this case, human misinterpretation is not an issue. .UNINDENT .INDENT 0.0 .TP .B DiagnoseSignedUnsignedCharComparisons When \fItrue\fP, the check will warn on \fBsigned char\fP/\fBunsigned char\fP comparisons, otherwise these comparisons are ignored. By default, this option is set to \fItrue\fP\&. .UNINDENT .SS bugprone\-sizeof\-container .sp The check finds usages of \fBsizeof\fP on expressions of STL container types. Most likely the user wanted to use \fB\&.size()\fP instead. .sp All class/struct types declared in namespace \fBstd::\fP having a const \fBsize()\fP method are considered containers, with the exception of \fBstd::bitset\fP and \fBstd::array\fP\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string s; int a = 47 + sizeof(s); // warning: sizeof() doesn\(aqt return the size of the container. Did you mean .size()? int b = sizeof(std::string); // no warning, probably intended. std::string array_of_strings[10]; int c = sizeof(array_of_strings) / sizeof(array_of_strings[0]); // no warning, definitely intended. std::array std_array; int d = sizeof(std_array); // no warning, probably intended. .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-sizeof\-expression .sp The check finds usages of \fBsizeof\fP expressions which are most likely errors. .sp The \fBsizeof\fP operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. Misuse of this operator may be leading to errors and possible software vulnerabilities. .SS Suspicious usage of \(aqsizeof(K)\(aq .sp A common mistake is to query the \fBsizeof\fP of an integer literal. This is equivalent to query the size of its type (probably \fBint\fP). The intent of the programmer was probably to simply get the integer and not its size. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #define BUFLEN 42 char buf[BUFLEN]; memset(buf, 0, sizeof(BUFLEN)); // sizeof(42) ==> sizeof(int) .ft P .fi .UNINDENT .UNINDENT .SS Suspicious usage of \(aqsizeof(expr)\(aq .sp In cases, where there is an enum or integer to represent a type, a common mistake is to query the \fBsizeof\fP on the integer or enum that represents the type that should be used by \fBsizeof\fP\&. This results in the size of the integer and not of the type the integer represents: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C enum data_type { FLOAT_TYPE, DOUBLE_TYPE }; struct data { data_type type; void* buffer; data_type get_type() { return type; } }; void f(data d, int numElements) { // should be sizeof(float) or sizeof(double), depending on d.get_type() int numBytes = numElements * sizeof(d.get_type()); ... } .ft P .fi .UNINDENT .UNINDENT .SS Suspicious usage of \(aqsizeof(this)\(aq .sp The \fBthis\fP keyword is evaluated to a pointer to an object of a given type. The expression \fBsizeof(this)\fP is returning the size of a pointer. The programmer most likely wanted the size of the object and not the size of the pointer. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Point { [...] size_t size() { return sizeof(this); } // should probably be sizeof(*this) [...] }; .ft P .fi .UNINDENT .UNINDENT .SS Suspicious usage of \(aqsizeof(char*)\(aq .sp There is a subtle difference between declaring a string literal with \fBchar* A = \(dq\(dq\fP and \fBchar A[] = \(dq\(dq\fP\&. The first case has the type \fBchar*\fP instead of the aggregate type \fBchar[]\fP\&. Using \fBsizeof\fP on an object declared with \fBchar*\fP type is returning the size of a pointer instead of the number of characters (bytes) in the string literal. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const char* kMessage = \(dqHello World!\(dq; // const char kMessage[] = \(dq...\(dq; void getMessage(char* buf) { memcpy(buf, kMessage, sizeof(kMessage)); // sizeof(char*) } .ft P .fi .UNINDENT .UNINDENT .SS Suspicious usage of \(aqsizeof(A*)\(aq .sp A common mistake is to compute the size of a pointer instead of its pointee. These cases may occur because of explicit cast or implicit conversion. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int A[10]; memset(A, 0, sizeof(A + 0)); struct Point point; memset(point, 0, sizeof(&point)); .ft P .fi .UNINDENT .UNINDENT .SS Suspicious usage of \(aqsizeof(...)/sizeof(...)\(aq .sp Dividing \fBsizeof\fP expressions is typically used to retrieve the number of elements of an aggregate. This check warns on incompatible or suspicious cases. .sp In the following example, the entity has 10\-bytes and is incompatible with the type \fBint\fP which has 4 bytes. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C char buf[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // sizeof(buf) => 10 void getMessage(char* dst) { memcpy(dst, buf, sizeof(buf) / sizeof(int)); // sizeof(int) => 4 [incompatible sizes] } .ft P .fi .UNINDENT .UNINDENT .sp In the following example, the expression \fBsizeof(Values)\fP is returning the size of \fBchar*\fP\&. One can easily be fooled by its declaration, but in parameter declaration the size \(aq10\(aq is ignored and the function is receiving a \fBchar*\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C char OrderedValues[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; return CompareArray(char Values[10]) { return memcmp(OrderedValues, Values, sizeof(Values)) == 0; // sizeof(Values) ==> sizeof(char*) [implicit cast to char*] } .ft P .fi .UNINDENT .UNINDENT .SS Suspicious \(aqsizeof\(aq by \(aqsizeof\(aq expression .sp Multiplying \fBsizeof\fP expressions typically makes no sense and is probably a logic error. In the following example, the programmer used \fB*\fP instead of \fB/\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const char kMessage[] = \(dqHello World!\(dq; void getMessage(char* buf) { memcpy(buf, kMessage, sizeof(kMessage) * sizeof(char)); // sizeof(kMessage) / sizeof(char) } .ft P .fi .UNINDENT .UNINDENT .sp This check may trigger on code using the arraysize macro. The following code is working correctly but should be simplified by using only the \fBsizeof\fP operator. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C extern Object objects[100]; void InitializeObjects() { memset(objects, 0, arraysize(objects) * sizeof(Object)); // sizeof(objects) } .ft P .fi .UNINDENT .UNINDENT .SS Suspicious usage of \(aqsizeof(sizeof(...))\(aq .sp Getting the \fBsizeof\fP of a \fBsizeof\fP makes no sense and is typically an error hidden through macros. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #define INT_SZ sizeof(int) int buf[] = { 42 }; void getInt(int* dst) { memcpy(dst, buf, sizeof(INT_SZ)); // sizeof(sizeof(int)) is suspicious. } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B WarnOnSizeOfConstant When \fItrue\fP, the check will warn on an expression like \fBsizeof(CONSTANT)\fP\&. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnOnSizeOfIntegerExpression When \fItrue\fP, the check will warn on an expression like \fBsizeof(expr)\fP where the expression results in an integer. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnOnSizeOfThis When \fItrue\fP, the check will warn on an expression like \fBsizeof(this)\fP\&. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnOnSizeOfCompareToConstant When \fItrue\fP, the check will warn on an expression like \fBsizeof(expr) <= k\fP for a suspicious constant \fIk\fP while \fIk\fP is \fI0\fP or greater than \fI0x8000\fP\&. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnOnSizeOfPointerToAggregate When \fItrue, the check will warn on an expression like \(ga\(gasizeof(expr)\(ga\fP where the expression is a pointer to aggregate. Default is \fItrue\fP\&. .UNINDENT .SS bugprone\-spuriously\-wake\-up\-functions .sp Finds \fBcnd_wait\fP, \fBcnd_timedwait\fP, \fBwait\fP, \fBwait_for\fP, or \fBwait_until\fP function calls when the function is not invoked from a loop that checks whether a condition predicate holds or the function has a condition parameter. .sp This check corresponds to the CERT C++ Coding Standard rule \fI\%CON54\-CPP. Wrap functions that can spuriously wake up in a loop\fP\&. and CERT C Coding Standard rule \fI\%CON36\-C. Wrap functions that can spuriously wake up in a loop\fP\&. .SS bugprone\-standalone\-empty .sp Warns when \fBempty()\fP is used on a range and the result is ignored. Suggests \fBclear()\fP if it is an existing member function. .sp The \fBempty()\fP method on several common ranges returns a Boolean indicating whether or not the range is empty, but is often mistakenly interpreted as a way to clear the contents of a range. Some ranges offer a \fBclear()\fP method for this purpose. This check warns when a call to empty returns a result that is ignored, and suggests replacing it with a call to \fBclear()\fP if it is available as a member function of the range. .sp For example, the following code could be used to indicate whether a range is empty or not, but the result is ignored: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector v; \&... v.empty(); .ft P .fi .UNINDENT .UNINDENT .sp A call to \fBclear()\fP would appropriately clear the contents of the range: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector v; \&... v.clear(); .ft P .fi .UNINDENT .UNINDENT .sp Limitations: .INDENT 0.0 .IP \(bu 2 Doesn\(aqt warn if \fBempty()\fP is defined and used with the ignore result in the class template definition (for example in the library implementation). These error cases can be caught with \fB[[nodiscard]]\fP attribute. .UNINDENT .SS bugprone\-string\-constructor .sp Finds string constructors that are suspicious and probably errors. .sp A common mistake is to swap parameters to the \(aqfill\(aq string\-constructor. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string str(\(aqx\(aq, 50); // should be str(50, \(aqx\(aq) .ft P .fi .UNINDENT .UNINDENT .sp Calling the string\-literal constructor with a length bigger than the literal is suspicious and adds extra random characters to the string. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string(\(dqtest\(dq, 200); // Will include random characters after \(dqtest\(dq. std::string_view(\(dqtest\(dq, 200); .ft P .fi .UNINDENT .UNINDENT .sp Creating an empty string from constructors with parameters is considered suspicious. The programmer should use the empty constructor instead. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string(\(dqtest\(dq, 0); // Creation of an empty string. std::string_view(\(dqtest\(dq, 0); .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B WarnOnLargeLength When \fItrue\fP, the check will warn on a string with a length greater than \fI\%LargeLengthThreshold\fP\&. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B LargeLengthThreshold An integer specifying the large length threshold. Default is \fI0x800000\fP\&. .UNINDENT .INDENT 0.0 .TP .B StringNames Default is \fI::std::basic_string;::std::basic_string_view\fP\&. .sp Semicolon\-delimited list of class names to apply this check to. By default \fI::std::basic_string\fP applies to \fBstd::string\fP and \fBstd::wstring\fP\&. Set to e.g. \fI::std::basic_string;llvm::StringRef;QString\fP to perform this check on custom classes. .UNINDENT .SS bugprone\-string\-integer\-assignment .sp The check finds assignments of an integer to \fBstd::basic_string\fP (\fBstd::string\fP, \fBstd::wstring\fP, etc.). The source of the problem is the following assignment operator of \fBstd::basic_string\fP: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C basic_string& operator=( CharT ch ); .ft P .fi .UNINDENT .UNINDENT .sp Numeric types can be implicitly casted to character types. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string s; int x = 5965; s = 6; s = x; .ft P .fi .UNINDENT .UNINDENT .sp Use the appropriate conversion functions or character literals. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string s; int x = 5965; s = \(aq6\(aq; s = std::to_string(x); .ft P .fi .UNINDENT .UNINDENT .sp In order to suppress false positives, use an explicit cast. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string s; s = static_cast(6); .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-string\-literal\-with\-embedded\-nul .sp Finds occurrences of string literal with embedded NUL character and validates their usage. .SS Invalid escaping .sp Special characters can be escaped within a string literal by using their hexadecimal encoding like \fB\ex42\fP\&. A common mistake is to escape them like this \fB\e0x42\fP where the \fB\e0\fP stands for the NUL character. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const char* Example[] = \(dqInvalid character: \e0x12 should be \ex12\(dq; const char* Bytes[] = \(dq\ex03\e0x02\e0x01\e0x00\e0xFF\e0xFF\e0xFF\(dq; .ft P .fi .UNINDENT .UNINDENT .SS Truncated literal .sp String\-like classes can manipulate strings with embedded NUL as they are keeping track of the bytes and the length. This is not the case for a \fBchar*\fP (NUL\-terminated) string. .sp A common mistake is to pass a string\-literal with embedded NUL to a string constructor expecting a NUL\-terminated string. The bytes after the first NUL character are truncated. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string str(\(dqabc\e0def\(dq); // \(dqdef\(dq is truncated str += \(dq\e0\(dq; // This statement is doing nothing if (str == \(dq\e0abc\(dq) return; // This expression is always true .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-stringview\-nullptr .sp Checks for various ways that the \fBconst CharT*\fP constructor of \fBstd::basic_string_view\fP can be passed a null argument and replaces them with the default constructor in most cases. For the comparison operators, braced initializer list does not compile so instead a call to \fB\&.empty()\fP or the empty string literal are used, where appropriate. .sp This prevents code from invoking behavior which is unconditionally undefined. The single\-argument \fBconst CharT*\fP constructor does not check for the null case before dereferencing its input. The standard is slated to add an explicitly\-deleted overload to catch some of these cases: wg21.link/p2166 .sp To catch the additional cases of \fBNULL\fP (which expands to \fB__null\fP) and \fB0\fP, first run the \fBmodernize\-use\-nullptr\fP check to convert the callers to \fBnullptr\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string_view sv = nullptr; sv = nullptr; bool is_empty = sv == nullptr; bool isnt_empty = sv != nullptr; accepts_sv(nullptr); accepts_sv({{}}); // A accepts_sv({nullptr, 0}); // B .ft P .fi .UNINDENT .UNINDENT .sp is translated into... .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string_view sv = {}; sv = {}; bool is_empty = sv.empty(); bool isnt_empty = !sv.empty(); accepts_sv(\(dq\(dq); accepts_sv(\(dq\(dq); // A accepts_sv({nullptr, 0}); // B .ft P .fi .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 The source pattern with trailing comment \(dqA\(dq selects the \fB(const CharT*)\fP constructor overload and then value\-initializes the pointer, causing a null dereference. It happens to not include the \fBnullptr\fP literal, but it is still within the scope of this ClangTidy check. .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 The source pattern with trailing comment \(dqB\(dq selects the \fB(const CharT*, size_type)\fP constructor which is perfectly valid, since the length argument is \fB0\fP\&. It is not changed by this ClangTidy check. .UNINDENT .UNINDENT .SS bugprone\-suspicious\-enum\-usage .sp The checker detects various cases when an enum is probably misused (as a bitmask ). .INDENT 0.0 .IP 1. 3 When \(dqADD\(dq or \(dqbitwise OR\(dq is used between two enum which come from different types and these types value ranges are not disjoint. .UNINDENT .sp The following cases will be investigated only using \fI\%StrictMode\fP\&. We regard the enum as a (suspicious) bitmask if the three conditions below are true at the same time: .INDENT 0.0 .IP \(bu 2 at most half of the elements of the enum are non pow\-of\-2 numbers (because of short enumerations) .IP \(bu 2 there is another non pow\-of\-2 number than the enum constant representing all choices (the result \(dqbitwise OR\(dq operation of all enum elements) .IP \(bu 2 enum type variable/enumconstant is used as an argument of a \fI+\fP or \(dqbitwise OR \(dq operator .UNINDENT .sp So whenever the non pow\-of\-2 element is used as a bitmask element we diagnose a misuse and give a warning. .INDENT 0.0 .IP 2. 3 Investigating the right hand side of \fI+=\fP and \fI|=\fP operator. .IP 3. 3 Check only the enum value side of a \fI|\fP and \fI+\fP operator if one of them is not enum val. .IP 4. 3 Check both side of \fI|\fP or \fI+\fP operator where the enum values are from the same enum type. .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C enum { A, B, C }; enum { D, E, F = 5 }; enum { G = 10, H = 11, I = 12 }; unsigned flag; flag = A | H; // OK, disjoint value intervals in the enum types \->probably good use. flag = B | F; // Warning, have common values so they are probably misused. // Case 2: enum Bitmask { A = 0, B = 1, C = 2, D = 4, E = 8, F = 16, G = 31 // OK, real bitmask. }; enum Almostbitmask { AA = 0, BB = 1, CC = 2, DD = 4, EE = 8, FF = 16, GG // Problem, forgot to initialize. }; unsigned flag = 0; flag |= E; // OK. flag |= EE; // Warning at the decl, and note that it was used here as a bitmask. .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B StrictMode Default value: 0. When non\-null the suspicious bitmask usage will be investigated additionally to the different enum usage check. .UNINDENT .SS bugprone\-suspicious\-include .sp The check detects various cases when an include refers to what appears to be an implementation file, which often leads to hard\-to\-track\-down ODR violations. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include \(dqDinosaur.hpp\(dq // OK, .hpp files tend not to have definitions. #include \(dqPterodactyl.h\(dq // OK, .h files tend not to have definitions. #include \(dqVelociraptor.cpp\(dq // Warning, filename is suspicious. #include_next // Warning, filename is suspicious. .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B HeaderFileExtensions Note: this option is deprecated, it will be removed in \fBclang\-tidy\fP version 19. Please use the global configuration option \fIHeaderFileExtensions\fP\&. .sp Default value: \fB\(dq;h;hh;hpp;hxx\(dq\fP A semicolon\-separated list of filename extensions of header files (the filename extensions should not contain a \(dq.\(dq prefix). For extension\-less header files, use an empty string or leave an empty string between \(dq;\(dq if there are other filename extensions. .UNINDENT .INDENT 0.0 .TP .B ImplementationFileExtensions Note: this option is deprecated, it will be removed in \fBclang\-tidy\fP version 19. Please use the global configuration option \fIImplementationFileExtensions\fP\&. .sp Default value: \fB\(dqc;cc;cpp;cxx\(dq\fP Likewise, a semicolon\-separated list of filename extensions of implementation files. .UNINDENT .SS bugprone\-suspicious\-memory\-comparison .sp Finds potentially incorrect calls to \fBmemcmp()\fP based on properties of the arguments. The following cases are covered: .sp \fBCase 1: Non\-standard\-layout type\fP .sp Comparing the object representations of non\-standard\-layout objects may not properly compare the value representations. .sp \fBCase 2: Types with no unique object representation\fP .sp Objects with the same value may not have the same object representation. This may be caused by padding or floating\-point types. .sp See also: \fI\%EXP42\-C. Do not compare padding data\fP and \fI\%FLP37\-C. Do not use object representations to compare floating\-point values\fP .sp This check is also related to and partially overlaps the CERT C++ Coding Standard rules \fI\%OOP57\-CPP. Prefer special member functions and overloaded operators to C Standard Library functions\fP and \fI\%EXP62\-CPP. Do not access the bits of an object representation that are not part of the object\(aqs value representation\fP .SS bugprone\-suspicious\-memset\-usage .sp This check finds \fBmemset()\fP calls with potential mistakes in their arguments. Considering the function as \fBvoid* memset(void* destination, int fill_value, size_t byte_count)\fP, the following cases are covered: .sp \fBCase 1: Fill value is a character \(ga\(ga\(aq0\(aq\(ga\(ga\fP .sp Filling up a memory area with ASCII code 48 characters is not customary, possibly integer zeroes were intended instead. The check offers a replacement of \fB\(aq0\(aq\fP with \fB0\fP\&. Memsetting character pointers with \fB\(aq0\(aq\fP is allowed. .sp \fBCase 2: Fill value is truncated\fP .sp Memset converts \fBfill_value\fP to \fBunsigned char\fP before using it. If \fBfill_value\fP is out of unsigned character range, it gets truncated and memory will not contain the desired pattern. .sp \fBCase 3: Byte count is zero\fP .sp Calling memset with a literal zero in its \fBbyte_count\fP argument is likely to be unintended and swapped with \fBfill_value\fP\&. The check offers to swap these two arguments. .sp Corresponding cpplint.py check name: \fBruntime/memset\fP\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo() { int i[5] = {1, 2, 3, 4, 5}; int *ip = i; char c = \(aq1\(aq; char *cp = &c; int v = 0; // Case 1 memset(ip, \(aq0\(aq, 1); // suspicious memset(cp, \(aq0\(aq, 1); // OK // Case 2 memset(ip, 0xabcd, 1); // fill value gets truncated memset(ip, 0x00, 1); // OK // Case 3 memset(ip, sizeof(int), v); // zero length, potentially swapped memset(ip, 0, 1); // OK } .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-suspicious\-missing\-comma .sp String literals placed side\-by\-side are concatenated at translation phase 6 (after the preprocessor). This feature is used to represent long string literal on multiple lines. .sp For instance, the following declarations are equivalent: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const char* A[] = \(dqThis is a test\(dq; const char* B[] = \(dqThis\(dq \(dq is a \(dq \(dqtest\(dq; .ft P .fi .UNINDENT .UNINDENT .sp A common mistake done by programmers is to forget a comma between two string literals in an array initializer list. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const char* Test[] = { \(dqline 1\(dq, \(dqline 2\(dq // Missing comma! \(dqline 3\(dq, \(dqline 4\(dq, \(dqline 5\(dq }; .ft P .fi .UNINDENT .UNINDENT .sp The array contains the string \(dqline 2line3\(dq at offset 1 (i.e. Test[1]). Clang won\(aqt generate warnings at compile time. .sp This check may warn incorrectly on cases like: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const char* SupportedFormat[] = { \(dqError %s\(dq, \(dqCode \(dq PRIu64, // May warn here. \(dqWarning %s\(dq, }; .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B SizeThreshold An unsigned integer specifying the minimum size of a string literal to be considered by the check. Default is \fB5U\fP\&. .UNINDENT .INDENT 0.0 .TP .B RatioThreshold A string specifying the maximum threshold ratio [0, 1.0] of suspicious string literals to be considered. Default is \fB\(dq.2\(dq\fP\&. .UNINDENT .INDENT 0.0 .TP .B MaxConcatenatedTokens An unsigned integer specifying the maximum number of concatenated tokens. Default is \fB5U\fP\&. .UNINDENT .SS bugprone\-suspicious\-realloc\-usage .sp This check finds usages of \fBrealloc\fP where the return value is assigned to the same expression as passed to the first argument: \fBp = realloc(p, size);\fP The problem with this construct is that if \fBrealloc\fP fails it returns a null pointer but does not deallocate the original memory. If no other variable is pointing to it, the original memory block is not available any more for the program to use or free. In either case \fBp = realloc(p, size);\fP indicates bad coding style and can be replaced by \fBq = realloc(p, size);\fP\&. .sp The pointer expression (used at \fBrealloc\fP) can be a variable or a field member of a data structure, but can not contain function calls or unresolved types. .sp In obvious cases when the pointer used at realloc is assigned to another variable before the \fBrealloc\fP call, no warning is emitted. This happens only if a simple expression in form of \fBq = p\fP or \fBvoid *q = p\fP is found in the same function where \fBp = realloc(p, ...)\fP is found. The assignment has to be before the call to realloc (but otherwise at any place) in the same function. This suppression works only if \fBp\fP is a single variable. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct A { void *p; }; A &getA(); void foo(void *p, A *a, int new_size) { p = realloc(p, new_size); // warning: \(aqp\(aq may be set to null if \(aqrealloc\(aq fails, which may result in a leak of the original buffer a\->p = realloc(a\->p, new_size); // warning: \(aqa\->p\(aq may be set to null if \(aqrealloc\(aq fails, which may result in a leak of the original buffer getA().p = realloc(getA().p, new_size); // no warning } void foo1(void *p, int new_size) { void *p1 = p; p = realloc(p, new_size); // no warning } .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-suspicious\-semicolon .sp Finds most instances of stray semicolons that unexpectedly alter the meaning of the code. More specifically, it looks for \fBif\fP, \fBwhile\fP, \fBfor\fP and \fBfor\-range\fP statements whose body is a single semicolon, and then analyzes the context of the code (e.g. indentation) in an attempt to determine whether that is intentional. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (x < y); { x++; } .ft P .fi .UNINDENT .UNINDENT .sp Here the body of the \fBif\fP statement consists of only the semicolon at the end of the first line, and \fIx\fP will be incremented regardless of the condition. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C while ((line = readLine(file)) != NULL); processLine(line); .ft P .fi .UNINDENT .UNINDENT .sp As a result of this code, \fIprocessLine()\fP will only be called once, when the \fBwhile\fP loop with the empty body exits with \fIline == NULL\fP\&. The indentation of the code indicates the intention of the programmer. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (x >= y); x \-= y; .ft P .fi .UNINDENT .UNINDENT .sp While the indentation does not imply any nesting, there is simply no valid reason to have an \fIif\fP statement with an empty body (but it can make sense for a loop). So this check issues a warning for the code above. .sp To solve the issue remove the stray semicolon or in case the empty body is intentional, reflect this using code indentation or put the semicolon in a new line. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C while (readWhitespace()); Token t = readNextToken(); .ft P .fi .UNINDENT .UNINDENT .sp Here the second line is indented in a way that suggests that it is meant to be the body of the \fIwhile\fP loop \- whose body is in fact empty, because of the semicolon at the end of the first line. .sp Either remove the indentation from the second line: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C while (readWhitespace()); Token t = readNextToken(); .ft P .fi .UNINDENT .UNINDENT .sp \&... or move the semicolon from the end of the first line to a new line: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C while (readWhitespace()) ; Token t = readNextToken(); .ft P .fi .UNINDENT .UNINDENT .sp In this case the check will assume that you know what you are doing, and will not raise a warning. .SS bugprone\-suspicious\-string\-compare .sp Find suspicious usage of runtime string comparison functions. This check is valid in C and C++. .sp Checks for calls with implicit comparator and proposed to explicitly add it. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (strcmp(...)) // Implicitly compare to zero if (!strcmp(...)) // Won\(aqt warn if (strcmp(...) != 0) // Won\(aqt warn .ft P .fi .UNINDENT .UNINDENT .sp Checks that compare function results (i.e., \fBstrcmp\fP) are compared to valid constant. The resulting value is .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C < 0 when lower than, > 0 when greater than, == 0 when equals. .ft P .fi .UNINDENT .UNINDENT .sp A common mistake is to compare the result to \fI1\fP or \fI\-1\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (strcmp(...) == \-1) // Incorrect usage of the returned value. .ft P .fi .UNINDENT .UNINDENT .sp Additionally, the check warns if the results value is implicitly cast to a \fIsuspicious\fP non\-integer type. It\(aqs happening when the returned value is used in a wrong context. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (strcmp(...) < 0.) // Incorrect usage of the returned value. .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B WarnOnImplicitComparison When \fItrue\fP, the check will warn on implicit comparison. \fItrue\fP by default. .UNINDENT .INDENT 0.0 .TP .B WarnOnLogicalNotComparison When \fItrue\fP, the check will warn on logical not comparison. \fIfalse\fP by default. .UNINDENT .INDENT 0.0 .TP .B StringCompareLikeFunctions A string specifying the comma\-separated names of the extra string comparison functions. Default is an empty string. The check will detect the following string comparison functions: \fI__builtin_memcmp\fP, \fI__builtin_strcasecmp\fP, \fI__builtin_strcmp\fP, \fI__builtin_strncasecmp\fP, \fI__builtin_strncmp\fP, \fI_mbscmp\fP, \fI_mbscmp_l\fP, \fI_mbsicmp\fP, \fI_mbsicmp_l\fP, \fI_mbsnbcmp\fP, \fI_mbsnbcmp_l\fP, \fI_mbsnbicmp\fP, \fI_mbsnbicmp_l\fP, \fI_mbsncmp\fP, \fI_mbsncmp_l\fP, \fI_mbsnicmp\fP, \fI_mbsnicmp_l\fP, \fI_memicmp\fP, \fI_memicmp_l\fP, \fI_stricmp\fP, \fI_stricmp_l\fP, \fI_strnicmp\fP, \fI_strnicmp_l\fP, \fI_wcsicmp\fP, \fI_wcsicmp_l\fP, \fI_wcsnicmp\fP, \fI_wcsnicmp_l\fP, \fIlstrcmp\fP, \fIlstrcmpi\fP, \fImemcmp\fP, \fImemicmp\fP, \fIstrcasecmp\fP, \fIstrcmp\fP, \fIstrcmpi\fP, \fIstricmp\fP, \fIstrncasecmp\fP, \fIstrncmp\fP, \fIstrnicmp\fP, \fIwcscasecmp\fP, \fIwcscmp\fP, \fIwcsicmp\fP, \fIwcsncmp\fP, \fIwcsnicmp\fP, \fIwmemcmp\fP\&. .UNINDENT .SS bugprone\-swapped\-arguments .sp Finds potentially swapped arguments by examining implicit conversions. It analyzes the types of the arguments being passed to a function and compares them to the expected types of the corresponding parameters. If there is a mismatch or an implicit conversion that indicates a potential swap, a warning is raised. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void printNumbers(int a, float b); int main() { // Swapped arguments: float passed as int, int as float) printNumbers(10.0f, 5); return 0; } .ft P .fi .UNINDENT .UNINDENT .sp Covers a wide range of implicit conversions, including: \- User\-defined conversions \- Conversions from floating\-point types to boolean or integral types \- Conversions from integral types to boolean or floating\-point types \- Conversions from boolean to integer types or floating\-point types \- Conversions from (member) pointers to boolean .sp It is important to note that for most argument swaps, the types need to match exactly. However, there are exceptions to this rule. Specifically, when the swapped argument is of integral type, an exact match is not always necessary. Implicit casts from other integral types are also accepted. Similarly, when dealing with floating\-point arguments, implicit casts between different floating\-point types are considered acceptable. .sp To avoid confusion, swaps where both swapped arguments are of integral types or both are of floating\-point types do not trigger the warning. In such cases, it\(aqs assumed that the developer intentionally used different integral or floating\-point types and does not raise a warning. This approach prevents false positives and provides flexibility in handling situations where varying integral or floating\-point types are intentionally utilized. .SS bugprone\-switch\-missing\-default\-case .sp Ensures that switch statements without default cases are flagged, focuses only on covering cases with non\-enums where the compiler may not issue warnings. .sp Switch statements without a default case can lead to unexpected behavior and incomplete handling of all possible cases. When a switch statement lacks a default case, if a value is encountered that does not match any of the specified cases, the program will continue execution without any defined behavior or handling. .sp This check helps identify switch statements that are missing a default case, allowing developers to ensure that all possible cases are handled properly. Adding a default case allows for graceful handling of unexpected or unmatched values, reducing the risk of program errors and unexpected behavior. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Example 1: // warning: switching on non\-enum value without default case may not cover all cases switch (i) { case 0: break; } // Example 2: enum E { eE1 }; E e = eE1; switch (e) { // no\-warning case eE1: break; } // Example 3: int i = 0; switch (i) { // no\-warning case 0: break; default: break; } .ft P .fi .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 Enum types are already covered by compiler warnings (comes under \-Wswitch) when a switch statement does not handle all enum values. This check focuses on non\-enum types where the compiler warnings may not be present. .UNINDENT .UNINDENT .sp \fBSEE ALSO:\fP .INDENT 0.0 .INDENT 3.5 The \fI\%CppCoreGuideline ES.79\fP provide guidelines on switch statements, including the recommendation to always provide a default case. .UNINDENT .UNINDENT .SS bugprone\-terminating\-continue .sp Detects \fBdo while\fP loops with a condition always evaluating to false that have a \fBcontinue\fP statement, as this \fBcontinue\fP terminates the loop effectively. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f() { do { // some code continue; // terminating continue // some other code } while(false); .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-throw\-keyword\-missing .sp Warns about a potentially missing \fBthrow\fP keyword. If a temporary object is created, but the object\(aqs type derives from (or is the same as) a class that has \(aqEXCEPTION\(aq, \(aqException\(aq or \(aqexception\(aq in its name, we can assume that the programmer\(aqs intention was to throw that object. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(int i) { if (i < 0) { // Exception is created but is not thrown. std::runtime_error(\(dqUnexpected argument\(dq); } } .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-too\-small\-loop\-variable .sp Detects those \fBfor\fP loops that have a loop variable with a \(dqtoo small\(dq type which means this type can\(aqt represent all values which are part of the iteration range. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int main() { long size = 294967296l; for (short i = 0; i < size; ++i) {} } .ft P .fi .UNINDENT .UNINDENT .sp This \fBfor\fP loop is an infinite loop because the \fBshort\fP type can\(aqt represent all values in the \fB[0..size]\fP interval. .sp In a real use case size means a container\(aqs size which depends on the user input. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int doSomething(const std::vector& items) { for (short i = 0; i < items.size(); ++i) {} } .ft P .fi .UNINDENT .UNINDENT .sp This algorithm works for a small amount of objects, but will lead to freeze for a larger user input. .INDENT 0.0 .TP .B MagnitudeBitsUpperLimit Upper limit for the magnitude bits of the loop variable. If it\(aqs set the check filters out those catches in which the loop variable\(aqs type has more magnitude bits as the specified upper limit. The default value is 16. For example, if the user sets this option to 31 (bits), then a 32\-bit \fBunsigned int\fP is ignored by the check, however a 32\-bit \fBint\fP is not (A 32\-bit \fBsigned int\fP has 31 magnitude bits). .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int main() { long size = 294967296l; for (unsigned i = 0; i < size; ++i) {} // no warning with MagnitudeBitsUpperLimit = 31 on a system where unsigned is 32\-bit for (int i = 0; i < size; ++i) {} // warning with MagnitudeBitsUpperLimit = 31 on a system where int is 32\-bit } .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-unchecked\-optional\-access .sp \fINote\fP: This check uses a flow\-sensitive static analysis to produce its results. Therefore, it may be more resource intensive (RAM, CPU) than the average clang\-tidy check. .sp This check identifies unsafe accesses to values contained in \fBstd::optional\fP, \fBabsl::optional\fP, \fBbase::Optional\fP, or \fBfolly::Optional\fP objects. Below we will refer to all these types collectively as \fBoptional\fP\&. .sp An access to the value of an \fBoptional\fP occurs when one of its \fBvalue\fP, \fBoperator*\fP, or \fBoperator\->\fP member functions is invoked. To align with common misconceptions, the check considers these member functions as equivalent, even though there are subtle differences related to exceptions versus undefined behavior. See \fIAdditional notes\fP, below, for more information on this topic. .sp An access to the value of an \fBoptional\fP is considered safe if and only if code in the local scope (for example, a function body) ensures that the \fBoptional\fP has a value in all possible execution paths that can reach the access. That should happen either through an explicit check, using the \fBoptional::has_value\fP member function, or by constructing the \fBoptional\fP in a way that shows that it unambiguously holds a value (e.g using \fBstd::make_optional\fP which always returns a populated \fBstd::optional\fP). .sp Below we list some examples, starting with unsafe optional access patterns, followed by safe access patterns. .SS Unsafe access patterns .SS Access the value without checking if it exists .sp The check flags accesses to the value that are not locally guarded by existence check: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(std::optional opt) { use(*opt); // unsafe: it is unclear whether \(gaopt\(ga has a value. } .ft P .fi .UNINDENT .UNINDENT .SS Access the value in the wrong branch .sp The check is aware of the state of an optional object in different branches of the code. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(std::optional opt) { if (opt.has_value()) { } else { use(opt.value()); // unsafe: it is clear that \(gaopt\(ga does *not* have a value. } } .ft P .fi .UNINDENT .UNINDENT .SS Assume a function result to be stable .sp The check is aware that function results might not be stable. That is, consecutive calls to the same function might return different values. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(Foo foo) { if (foo.opt().has_value()) { use(*foo.opt()); // unsafe: it is unclear whether \(gafoo.opt()\(ga has a value. } } .ft P .fi .UNINDENT .UNINDENT .SS Rely on invariants of uncommon APIs .sp The check is unaware of invariants of uncommon APIs. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(Foo foo) { if (foo.HasProperty(\(dqbar\(dq)) { use(*foo.GetProperty(\(dqbar\(dq)); // unsafe: it is unclear whether \(gafoo.GetProperty(\(dqbar\(dq)\(ga has a value. } } .ft P .fi .UNINDENT .UNINDENT .SS Check if a value exists, then pass the optional to another function .sp The check relies on local reasoning. The check and value access must both happen in the same function. An access is considered unsafe even if the caller of the function performing the access ensures that the optional has a value. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void g(std::optional opt) { use(*opt); // unsafe: it is unclear whether \(gaopt\(ga has a value. } void f(std::optional opt) { if (opt.has_value()) { g(opt); } } .ft P .fi .UNINDENT .UNINDENT .SS Safe access patterns .SS Check if a value exists, then access the value .sp The check recognizes all straightforward ways for checking if a value exists and accessing the value contained in an optional object. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(std::optional opt) { if (opt.has_value()) { use(*opt); } } .ft P .fi .UNINDENT .UNINDENT .SS Check if a value exists, then access the value from a copy .sp The criteria that the check uses is semantic, not syntactic. It recognizes when a copy of the optional object being accessed is known to have a value. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(std::optional opt1) { if (opt1.has_value()) { std::optional opt2 = opt1; use(*opt2); } } .ft P .fi .UNINDENT .UNINDENT .SS Ensure that a value exists using common macros .sp The check is aware of common macros like \fBCHECK\fP and \fBDCHECK\fP\&. Those can be used to ensure that an optional object has a value. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(std::optional opt) { DCHECK(opt.has_value()); use(*opt); } .ft P .fi .UNINDENT .UNINDENT .SS Ensure that a value exists, then access the value in a correlated branch .sp The check is aware of correlated branches in the code and can figure out when an optional object is ensured to have a value on all execution paths that lead to an access. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(std::optional opt) { bool safe = false; if (opt.has_value() && SomeOtherCondition()) { safe = true; } // ... more code... if (safe) { use(*opt); } } .ft P .fi .UNINDENT .UNINDENT .SS Stabilize function results .sp Since function results are not assumed to be stable across calls, it is best to store the result of the function call in a local variable and use that variable to access the value. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(Foo foo) { if (const auto& foo_opt = foo.opt(); foo_opt.has_value()) { use(*foo_opt); } } .ft P .fi .UNINDENT .UNINDENT .SS Do not rely on uncommon\-API invariants .sp When uncommon APIs guarantee that an optional has contents, do not rely on it \-\- instead, check explicitly that the optional object has a value. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(Foo foo) { if (const auto& property = foo.GetProperty(\(dqbar\(dq)) { use(*property); } } .ft P .fi .UNINDENT .UNINDENT .sp instead of the \fIHasProperty\fP, \fIGetProperty\fP pairing we saw above. .SS Do not rely on caller\-performed checks .sp If you know that all of a function\(aqs callers have checked that an optional argument has a value, either change the function to take the value directly or check the optional again in the local scope of the callee. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void g(int val) { use(val); } void f(std::optional opt) { if (opt.has_value()) { g(*opt); } } .ft P .fi .UNINDENT .UNINDENT .sp and .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct S { std::optional opt; int x; }; void g(const S &s) { if (s.opt.has_value() && s.x > 10) { use(*s.opt); } void f(S s) { if (s.opt.has_value()) { g(s); } } .ft P .fi .UNINDENT .UNINDENT .SS Additional notes .SS Aliases created via \fBusing\fP declarations .sp The check is aware of aliases of optional types that are created via \fBusing\fP declarations. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C using OptionalInt = std::optional; void f(OptionalInt opt) { use(opt.value()); // unsafe: it is unclear whether \(gaopt\(ga has a value. } .ft P .fi .UNINDENT .UNINDENT .SS Lambdas .sp The check does not currently report unsafe optional accesses in lambdas. A future version will expand the scope to lambdas, following the rules outlined above. It is best to follow the same principles when using optionals in lambdas. .SS Access with \fBoperator*()\fP vs. \fBvalue()\fP .sp Given that \fBvalue()\fP has well\-defined behavior (either throwing an exception or terminating the program), why treat it the same as \fBoperator*()\fP which causes undefined behavior (UB)? That is, why is it considered unsafe to access an optional with \fBvalue()\fP, if it\(aqs not provably populated with a value? For that matter, why is \fBCHECK()\fP followed by \fBoperator*()\fP any better than \fBvalue()\fP, given that they are semantically equivalent (on configurations that disable exceptions)? .sp The answer is that we assume most users do not realize the difference between \fBvalue()\fP and \fBoperator*()\fP\&. Shifting to \fBoperator*()\fP and some form of explicit value\-presence check or explicit program termination has two advantages: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 Readability. The check, and any potential side effects like program shutdown, are very clear in the code. Separating access from checks can actually make the checks more obvious. .IP \(bu 2 Performance. A single check can cover many or even all accesses within scope. This gives the user the best of both worlds \-\- the safety of a dynamic check, but without incurring redundant costs. .UNINDENT .UNINDENT .UNINDENT .SS bugprone\-undefined\-memory\-manipulation .sp Finds calls of memory manipulation functions \fBmemset()\fP, \fBmemcpy()\fP and \fBmemmove()\fP on not TriviallyCopyable objects resulting in undefined behavior. .SS bugprone\-undelegated\-constructor .sp Finds creation of temporary objects in constructors that look like a function call to another constructor of the same class. .sp The user most likely meant to use a delegating constructor or base class initializer. .SS bugprone\-unhandled\-exception\-at\-new .sp Finds calls to \fBnew\fP with missing exception handler for \fBstd::bad_alloc\fP\&. .sp Calls to \fBnew\fP may throw exceptions of type \fBstd::bad_alloc\fP that should be handled. Alternatively, the nonthrowing form of \fBnew\fP can be used. The check verifies that the exception is handled in the function that calls \fBnew\fP\&. .sp If a nonthrowing version is used or the exception is allowed to propagate out of the function no warning is generated. .sp The exception handler is checked if it catches a \fBstd::bad_alloc\fP or \fBstd::exception\fP exception type, or all exceptions (catch\-all). The check assumes that any user\-defined \fBoperator new\fP is either \fBnoexcept\fP or may throw an exception of type \fBstd::bad_alloc\fP (or one derived from it). Other exception class types are not taken into account. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int *f() noexcept { int *p = new int[1000]; // warning: missing exception handler for allocation failure at \(aqnew\(aq // ... return p; } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int *f1() { // not \(aqnoexcept\(aq int *p = new int[1000]; // no warning: exception can be handled outside // of this function // ... return p; } int *f2() noexcept { try { int *p = new int[1000]; // no warning: exception is handled // ... return p; } catch (std::bad_alloc &) { // ... } // ... } int *f3() noexcept { int *p = new (std::nothrow) int[1000]; // no warning: \(dqnothrow\(dq is used // ... return p; } .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-unhandled\-self\-assignment .sp \fIcert\-oop54\-cpp\fP redirects here as an alias for this check. For the CERT alias, the \fIWarnOnlyIfThisHasSuspiciousField\fP option is set to \fIfalse\fP\&. .sp Finds user\-defined copy assignment operators which do not protect the code against self\-assignment either by checking self\-assignment explicitly or using the copy\-and\-swap or the copy\-and\-move method. .sp By default, this check searches only those classes which have any pointer or C array field to avoid false positives. In case of a pointer or a C array, it\(aqs likely that self\-copy assignment breaks the object if the copy assignment operator was not written with care. .sp See also: \fI\%OOP54\-CPP. Gracefully handle self\-copy assignment\fP .sp A copy assignment operator must prevent that self\-copy assignment ruins the object state. A typical use case is when the class has a pointer field and the copy assignment operator first releases the pointed object and then tries to assign it: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class T { int* p; public: T(const T &rhs) : p(rhs.p ? new int(*rhs.p) : nullptr) {} ~T() { delete p; } // ... T& operator=(const T &rhs) { delete p; p = new int(*rhs.p); return *this; } }; .ft P .fi .UNINDENT .UNINDENT .sp There are two common C++ patterns to avoid this problem. The first is the self\-assignment check: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class T { int* p; public: T(const T &rhs) : p(rhs.p ? new int(*rhs.p) : nullptr) {} ~T() { delete p; } // ... T& operator=(const T &rhs) { if(this == &rhs) return *this; delete p; p = new int(*rhs.p); return *this; } }; .ft P .fi .UNINDENT .UNINDENT .sp The second one is the copy\-and\-swap method when we create a temporary copy (using the copy constructor) and then swap this temporary object with \fBthis\fP: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class T { int* p; public: T(const T &rhs) : p(rhs.p ? new int(*rhs.p) : nullptr) {} ~T() { delete p; } // ... void swap(T &rhs) { using std::swap; swap(p, rhs.p); } T& operator=(const T &rhs) { T(rhs).swap(*this); return *this; } }; .ft P .fi .UNINDENT .UNINDENT .sp There is a third pattern which is less common. Let\(aqs call it the copy\-and\-move method when we create a temporary copy (using the copy constructor) and then move this temporary object into \fBthis\fP (needs a move assignment operator): .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class T { int* p; public: T(const T &rhs) : p(rhs.p ? new int(*rhs.p) : nullptr) {} ~T() { delete p; } // ... T& operator=(const T &rhs) { T t = rhs; *this = std::move(t); return *this; } T& operator=(T &&rhs) { p = rhs.p; rhs.p = nullptr; return *this; } }; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B WarnOnlyIfThisHasSuspiciousField When \fItrue\fP, the check will warn only if the container class of the copy assignment operator has any suspicious fields (pointer or C array). This option is set to \fItrue\fP by default. .UNINDENT .SS bugprone\-unique\-ptr\-array\-mismatch .sp Finds initializations of C++ unique pointers to non\-array type that are initialized with an array. .sp If a pointer \fBstd::unique_ptr\fP is initialized with a new\-expression \fBnew T[]\fP the memory is not deallocated correctly. A plain \fBdelete\fP is used in this case to deallocate the target memory. Instead a \fBdelete[]\fP call is needed. A \fBstd::unique_ptr\fP uses the correct delete operator. The check does not emit warning if an \fBunique_ptr\fP with user\-specified deleter type is used. .sp The check offers replacement of \fBunique_ptr\fP to \fBunique_ptr\fP if it is used at a single variable declaration (one variable in one statement). .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::unique_ptr x(new Foo[10]); // \-> std::unique_ptr x(new Foo[10]); // ^ warning: unique pointer to non\-array is initialized with array std::unique_ptr x1(new Foo), x2(new Foo[10]); // no replacement // ^ warning: unique pointer to non\-array is initialized with array D d; std::unique_ptr x3(new Foo[10], d); // no warning (custom deleter used) struct S { std::unique_ptr x(new Foo[10]); // no replacement in this case // ^ warning: unique pointer to non\-array is initialized with array }; .ft P .fi .UNINDENT .UNINDENT .sp This check partially covers the CERT C++ Coding Standard rule \fI\%MEM51\-CPP. Properly deallocate dynamically allocated resources\fP However, only the \fBstd::unique_ptr\fP case is detected by this check. .SS bugprone\-unsafe\-functions .sp Checks for functions that have safer, more secure replacements available, or are considered deprecated due to design flaws. The check heavily relies on the functions from the \fBAnnex K.\fP \(dqBounds\-checking interfaces\(dq of C11. .INDENT 0.0 .TP .B The check implements the following rules from the CERT C Coding Standard: .INDENT 7.0 .IP \(bu 2 Recommendation \fI\%MSC24\-C. Do not use deprecated or obsolescent functions\fP\&. .IP \(bu 2 Rule \fI\%MSC33\-C. Do not pass invalid data to the asctime() function\fP\&. .UNINDENT .UNINDENT .sp \fIcert\-msc24\-c\fP and \fIcert\-msc33\-c\fP redirect here as aliases of this check. .SS Unsafe functions .sp If \fIAnnex K.\fP is available, a replacement from \fIAnnex K.\fP is suggested for the following functions: .sp \fBasctime\fP, \fBasctime_r\fP, \fBbsearch\fP, \fBctime\fP, \fBfopen\fP, \fBfprintf\fP, \fBfreopen\fP, \fBfscanf\fP, \fBfwprintf\fP, \fBfwscanf\fP, \fBgetenv\fP, \fBgets\fP, \fBgmtime\fP, \fBlocaltime\fP, \fBmbsrtowcs\fP, \fBmbstowcs\fP, \fBmemcpy\fP, \fBmemmove\fP, \fBmemset\fP, \fBprintf\fP, \fBqsort\fP, \fBscanf\fP, \fBsnprintf\fP, \fBsprintf\fP, \fBsscanf\fP, \fBstrcat\fP, \fBstrcpy\fP, \fBstrerror\fP, \fBstrlen\fP, \fBstrncat\fP, \fBstrncpy\fP, \fBstrtok\fP, \fBswprintf\fP, \fBswscanf\fP, \fBvfprintf\fP, \fBvfscanf\fP, \fBvfwprintf\fP, \fBvfwscanf\fP, \fBvprintf\fP, \fBvscanf\fP, \fBvsnprintf\fP, \fBvsprintf\fP, \fBvsscanf\fP, \fBvswprintf\fP, \fBvswscanf\fP, \fBvwprintf\fP, \fBvwscanf\fP, \fBwcrtomb\fP, \fBwcscat\fP, \fBwcscpy\fP, \fBwcslen\fP, \fBwcsncat\fP, \fBwcsncpy\fP, \fBwcsrtombs\fP, \fBwcstok\fP, \fBwcstombs\fP, \fBwctomb\fP, \fBwmemcpy\fP, \fBwmemmove\fP, \fBwprintf\fP, \fBwscanf\fP\&. .sp If \fIAnnex K.\fP is not available, replacements are suggested only for the following functions from the previous list: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBasctime\fP, \fBasctime_r\fP, suggested replacement: \fBstrftime\fP .IP \(bu 2 \fBgets\fP, suggested replacement: \fBfgets\fP .UNINDENT .UNINDENT .UNINDENT .sp The following functions are always checked, regardless of \fIAnnex K\fP availability: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBrewind\fP, suggested replacement: \fBfseek\fP .IP \(bu 2 \fBsetbuf\fP, suggested replacement: \fBsetvbuf\fP .UNINDENT .UNINDENT .UNINDENT .sp If \fI\%ReportMoreUnsafeFunctions\fP is enabled, the following functions are also checked: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBbcmp\fP, suggested replacement: \fBmemcmp\fP .IP \(bu 2 \fBbcopy\fP, suggested replacement: \fBmemcpy_s\fP if \fIAnnex K\fP is available, or \fBmemcpy\fP .IP \(bu 2 \fBbzero\fP, suggested replacement: \fBmemset_s\fP if \fIAnnex K\fP is available, or \fBmemset\fP .IP \(bu 2 \fBgetpw\fP, suggested replacement: \fBgetpwuid\fP .IP \(bu 2 \fBvfork\fP, suggested replacement: \fBposix_spawn\fP .UNINDENT .UNINDENT .UNINDENT .sp Although mentioned in the associated CERT rules, the following functions are \fBignored\fP by the check: .sp \fBatof\fP, \fBatoi\fP, \fBatol\fP, \fBatoll\fP, \fBtmpfile\fP\&. .sp The availability of \fIAnnex K\fP is determined based on the following macros: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fB__STDC_LIB_EXT1__\fP: feature macro, which indicates the presence of \fIAnnex K. \(dqBounds\-checking interfaces\(dq\fP in the library implementation .IP \(bu 2 \fB__STDC_WANT_LIB_EXT1__\fP: user\-defined macro, which indicates that the user requests the functions from \fIAnnex K.\fP to be defined. .UNINDENT .UNINDENT .UNINDENT .sp Both macros have to be defined to suggest replacement functions from \fIAnnex K.\fP \fB__STDC_LIB_EXT1__\fP is defined by the library implementation, and \fB__STDC_WANT_LIB_EXT1__\fP must be defined to \fB1\fP by the user \fBbefore\fP including any system headers. .SS Options .INDENT 0.0 .TP .B ReportMoreUnsafeFunctions When \fItrue\fP, additional functions from widely used APIs (such as POSIX) are added to the list of reported functions. See the main documentation of the check for the complete list as to what this option enables. Default is \fItrue\fP\&. .UNINDENT .SS Examples .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #ifndef __STDC_LIB_EXT1__ #error \(dqAnnex K is not supported by the current standard library implementation.\(dq #endif #define __STDC_WANT_LIB_EXT1__ 1 #include // Defines functions from Annex K. #include enum { BUFSIZE = 32 }; void Unsafe(const char *Msg) { static const char Prefix[] = \(dqError: \(dq; static const char Suffix[] = \(dq\en\(dq; char Buf[BUFSIZE] = {0}; strcpy(Buf, Prefix); // warning: function \(aqstrcpy\(aq is not bounds\-checking; \(aqstrcpy_s\(aq should be used instead. strcat(Buf, Msg); // warning: function \(aqstrcat\(aq is not bounds\-checking; \(aqstrcat_s\(aq should be used instead. strcat(Buf, Suffix); // warning: function \(aqstrcat\(aq is not bounds\-checking; \(aqstrcat_s\(aq should be used instead. if (fputs(buf, stderr) < 0) { // error handling return; } } void UsingSafeFunctions(const char *Msg) { static const char Prefix[] = \(dqError: \(dq; static const char Suffix[] = \(dq\en\(dq; char Buf[BUFSIZE] = {0}; if (strcpy_s(Buf, BUFSIZE, Prefix) != 0) { // error handling return; } if (strcat_s(Buf, BUFSIZE, Msg) != 0) { // error handling return; } if (strcat_s(Buf, BUFSIZE, Suffix) != 0) { // error handling return; } if (fputs(Buf, stderr) < 0) { // error handling return; } } .ft P .fi .UNINDENT .UNINDENT .SS bugprone\-unused\-raii .sp Finds temporaries that look like RAII objects. .sp The canonical example for this is a scoped lock. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C { scoped_lock(&global_mutex); critical_section(); } .ft P .fi .UNINDENT .UNINDENT .sp The destructor of the scoped_lock is called before the \fBcritical_section\fP is entered, leaving it unprotected. .sp We apply a number of heuristics to reduce the false positive count of this check: .INDENT 0.0 .IP \(bu 2 Ignore code expanded from macros. Testing frameworks make heavy use of this. .IP \(bu 2 Ignore types with trivial destructors. They are very unlikely to be RAII objects and there\(aqs no difference when they are deleted. .IP \(bu 2 Ignore objects at the end of a compound statement (doesn\(aqt change behavior). .IP \(bu 2 Ignore objects returned from a call. .UNINDENT .SS bugprone\-unused\-return\-value .sp Warns on unused function return values. The checked functions can be configured. .SS Options .INDENT 0.0 .TP .B CheckedFunctions Semicolon\-separated list of functions to check. The function is checked if the name and scope matches, with any arguments. By default the following functions are checked: \fBstd::async, std::launder, std::remove, std::remove_if, std::unique, std::unique_ptr::release, std::basic_string::empty, std::vector::empty, std::back_inserter, std::distance, std::find, std::find_if, std::inserter, std::lower_bound, std::make_pair, std::map::count, std::map::find, std::map::lower_bound, std::multimap::equal_range, std::multimap::upper_bound, std::set::count, std::set::find, std::setfill, std::setprecision, std::setw, std::upper_bound, std::vector::at, bsearch, ferror, feof, isalnum, isalpha, isblank, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, iswalnum, iswprint, iswspace, isxdigit, memchr, memcmp, strcmp, strcoll, strncmp, strpbrk, strrchr, strspn, strstr, wcscmp, access, bind, connect, difftime, dlsym, fnmatch, getaddrinfo, getopt, htonl, htons, iconv_open, inet_addr, isascii, isatty, mmap, newlocale, openat, pathconf, pthread_equal, pthread_getspecific, pthread_mutex_trylock, readdir, readlink, recvmsg, regexec, scandir, semget, setjmp, shm_open, shmget, sigismember, strcasecmp, strsignal, ttyname\fP .INDENT 7.0 .IP \(bu 2 \fBstd::async()\fP\&. Not using the return value makes the call synchronous. .IP \(bu 2 \fBstd::launder()\fP\&. Not using the return value usually means that the function interface was misunderstood by the programmer. Only the returned pointer is \(dqlaundered\(dq, not the argument. .IP \(bu 2 \fBstd::remove()\fP, \fBstd::remove_if()\fP and \fBstd::unique()\fP\&. The returned iterator indicates the boundary between elements to keep and elements to be removed. Not using the return value means that the information about which elements to remove is lost. .IP \(bu 2 \fBstd::unique_ptr::release()\fP\&. Not using the return value can lead to resource leaks if the same pointer isn\(aqt stored anywhere else. Often, ignoring the \fBrelease()\fP return value indicates that the programmer confused the function with \fBreset()\fP\&. .IP \(bu 2 \fBstd::basic_string::empty()\fP and \fBstd::vector::empty()\fP\&. Not using the return value often indicates that the programmer confused the function with \fBclear()\fP\&. .UNINDENT .UNINDENT .INDENT 0.0 .TP .B CheckedReturnTypes Semicolon\-separated list of function return types to check. By default the following function return types are checked: \fI::std::error_code\fP, \fI::std::error_condition\fP, \fI::std::errc\fP, \fI::std::expected\fP, \fI::boost::system::error_code\fP .UNINDENT .sp \fI\%cert\-err33\-c\fP is an alias of this check that checks a fixed and large set of standard library functions. .SS bugprone\-use\-after\-move .sp Warns if an object is used after it has been moved, for example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string str = \(dqHello, world!\en\(dq; std::vector messages; messages.emplace_back(std::move(str)); std::cout << str; .ft P .fi .UNINDENT .UNINDENT .sp The last line will trigger a warning that \fBstr\fP is used after it has been moved. .sp The check does not trigger a warning if the object is reinitialized after the move and before the use. For example, no warning will be output for this code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C messages.emplace_back(std::move(str)); str = \(dqGreetings, stranger!\en\(dq; std::cout << str; .ft P .fi .UNINDENT .UNINDENT .sp Subsections below explain more precisely what exactly the check considers to be a move, use, and reinitialization. .sp The check takes control flow into account. A warning is only emitted if the use can be reached from the move. This means that the following code does not produce a warning: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (condition) { messages.emplace_back(std::move(str)); } else { std::cout << str; } .ft P .fi .UNINDENT .UNINDENT .sp On the other hand, the following code does produce a warning: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C for (int i = 0; i < 10; ++i) { std::cout << str; messages.emplace_back(std::move(str)); } .ft P .fi .UNINDENT .UNINDENT .sp (The use\-after\-move happens on the second iteration of the loop.) .sp In some cases, the check may not be able to detect that two branches are mutually exclusive. For example (assuming that \fBi\fP is an int): .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (i == 1) { messages.emplace_back(std::move(str)); } if (i == 2) { std::cout << str; } .ft P .fi .UNINDENT .UNINDENT .sp In this case, the check will erroneously produce a warning, even though it is not possible for both the move and the use to be executed. More formally, the analysis is \fI\%flow\-sensitive but not path\-sensitive\fP\&. .SS Silencing erroneous warnings .sp An erroneous warning can be silenced by reinitializing the object after the move: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (i == 1) { messages.emplace_back(std::move(str)); str = \(dq\(dq; } if (i == 2) { std::cout << str; } .ft P .fi .UNINDENT .UNINDENT .sp If you want to avoid the overhead of actually reinitializing the object, you can create a dummy function that causes the check to assume the object was reinitialized: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C template void IS_INITIALIZED(T&) {} .ft P .fi .UNINDENT .UNINDENT .sp You can use this as follows: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (i == 1) { messages.emplace_back(std::move(str)); } if (i == 2) { IS_INITIALIZED(str); std::cout << str; } .ft P .fi .UNINDENT .UNINDENT .sp The check will not output a warning in this case because passing the object to a function as a non\-const pointer or reference counts as a reinitialization (see section \fI\%Reinitialization\fP below). .SS Unsequenced moves, uses, and reinitializations .sp In many cases, C++ does not make any guarantees about the order in which sub\-expressions of a statement are evaluated. This means that in code like the following, it is not guaranteed whether the use will happen before or after the move: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(int i, std::vector v); std::vector v = { 1, 2, 3 }; f(v[1], std::move(v)); .ft P .fi .UNINDENT .UNINDENT .sp In this kind of situation, the check will note that the use and move are unsequenced. .sp The check will also take sequencing rules into account when reinitializations occur in the same statement as moves or uses. A reinitialization is only considered to reinitialize a variable if it is guaranteed to be evaluated after the move and before the use. .SS Move .sp The check currently only considers calls of \fBstd::move\fP on local variables or function parameters. It does not check moves of member variables or global variables. .sp Any call of \fBstd::move\fP on a variable is considered to cause a move of that variable, even if the result of \fBstd::move\fP is not passed to an rvalue reference parameter. .sp This means that the check will flag a use\-after\-move even on a type that does not define a move constructor or move assignment operator. This is intentional. Developers may use \fBstd::move\fP on such a type in the expectation that the type will add move semantics in the future. If such a \fBstd::move\fP has the potential to cause a use\-after\-move, we want to warn about it even if the type does not implement move semantics yet. .sp Furthermore, if the result of \fBstd::move\fP \fIis\fP passed to an rvalue reference parameter, this will always be considered to cause a move, even if the function that consumes this parameter does not move from it, or if it does so only conditionally. For example, in the following situation, the check will assume that a move always takes place: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector messages; void f(std::string &&str) { // Only remember the message if it isn\(aqt empty. if (!str.empty()) { messages.emplace_back(std::move(str)); } } std::string str = \(dq\(dq; f(std::move(str)); .ft P .fi .UNINDENT .UNINDENT .sp The check will assume that the last line causes a move, even though, in this particular case, it does not. Again, this is intentional. .sp There is one special case: A call to \fBstd::move\fP inside a \fBtry_emplace\fP call is conservatively assumed not to move. This is to avoid spurious warnings, as the check has no way to reason about the \fBbool\fP returned by \fBtry_emplace\fP\&. .sp When analyzing the order in which moves, uses and reinitializations happen (see section \fI\%Unsequenced moves, uses, and reinitializations\fP), the move is assumed to occur in whichever function the result of the \fBstd::move\fP is passed to. .SS Use .sp Any occurrence of the moved variable that is not a reinitialization (see below) is considered to be a use. .sp An exception to this are objects of type \fBstd::unique_ptr\fP, \fBstd::shared_ptr\fP and \fBstd::weak_ptr\fP, which have defined move behavior (objects of these classes are guaranteed to be empty after they have been moved from). Therefore, an object of these classes will only be considered to be used if it is dereferenced, i.e. if \fBoperator*\fP, \fBoperator\->\fP or \fBoperator[]\fP (in the case of \fBstd::unique_ptr\fP) is called on it. .sp If multiple uses occur after a move, only the first of these is flagged. .SS Reinitialization .sp The check considers a variable to be reinitialized in the following cases: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 The variable occurs on the left\-hand side of an assignment. .IP \(bu 2 The variable is passed to a function as a non\-const pointer or non\-const lvalue reference. (It is assumed that the variable may be an out\-parameter for the function.) .IP \(bu 2 \fBclear()\fP or \fBassign()\fP is called on the variable and the variable is of one of the standard container types \fBbasic_string\fP, \fBvector\fP, \fBdeque\fP, \fBforward_list\fP, \fBlist\fP, \fBset\fP, \fBmap\fP, \fBmultiset\fP, \fBmultimap\fP, \fBunordered_set\fP, \fBunordered_map\fP, \fBunordered_multiset\fP, \fBunordered_multimap\fP\&. .IP \(bu 2 \fBreset()\fP is called on the variable and the variable is of type \fBstd::unique_ptr\fP, \fBstd::shared_ptr\fP or \fBstd::weak_ptr\fP\&. .IP \(bu 2 A member function marked with the \fB[[clang::reinitializes]]\fP attribute is called on the variable. .UNINDENT .UNINDENT .UNINDENT .sp If the variable in question is a struct and an individual member variable of that struct is written to, the check does not consider this to be a reinitialization \-\- even if, eventually, all member variables of the struct are written to. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct S { std::string str; int i; }; S s = { \(dqHello, world!\en\(dq, 42 }; S s_other = std::move(s); s.str = \(dqLorem ipsum\(dq; s.i = 99; .ft P .fi .UNINDENT .UNINDENT .sp The check will not consider \fBs\fP to be reinitialized after the last line; instead, the line that assigns to \fBs.str\fP will be flagged as a use\-after\-move. This is intentional as this pattern of reinitializing a struct is error\-prone. For example, if an additional member variable is added to \fBS\fP, it is easy to forget to add the reinitialization for this additional member. Instead, it is safer to assign to the entire struct in one go, and this will also avoid the use\-after\-move warning. .SS bugprone\-virtual\-near\-miss .sp Warn if a function is a near miss (i.e. the name is very similar and the function signature is the same) to a virtual function from a base class. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct Base { virtual void func(); }; struct Derived : Base { virtual void funk(); // warning: \(aqDerived::funk\(aq has a similar name and the same signature as virtual method \(aqBase::func\(aq; did you mean to override it? }; .ft P .fi .UNINDENT .UNINDENT .SS cert\-con36\-c .sp The cert\-con36\-c check is an alias, please see \fI\%bugprone\-spuriously\-wake\-up\-functions\fP for more information. .SS cert\-con54\-cpp .sp The cert\-con54\-cpp check is an alias, please see \fI\%bugprone\-spuriously\-wake\-up\-functions\fP for more information. .SS cert\-dcl03\-c .sp The cert\-dcl03\-c check is an alias, please see \fI\%misc\-static\-assert\fP for more information. .SS cert\-dcl16\-c .sp The cert\-dcl16\-c check is an alias, please see \fI\%readability\-uppercase\-literal\-suffix\fP for more information. .SS cert\-dcl21\-cpp .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 This check is deprecated since it\(aqs no longer part of the CERT standard. It will be removed in \fBclang\-tidy\fP version 19. .UNINDENT .UNINDENT .sp This check flags postfix \fBoperator++\fP and \fBoperator\-\-\fP declarations if the return type is not a const object. This also warns if the return type is a reference type. .sp The object returned by a postfix increment or decrement operator is supposed to be a snapshot of the object\(aqs value prior to modification. With such an implementation, any modifications made to the resulting object from calling operator++(int) would be modifying a temporary object. Thus, such an implementation of a postfix increment or decrement operator should instead return a const object, prohibiting accidental mutation of a temporary object. Similarly, it is unexpected for the postfix operator to return a reference to its previous state, and any subsequent modifications would be operating on a stale object. .sp This check corresponds to the CERT C++ Coding Standard recommendation DCL21\-CPP. Overloaded postfix increment and decrement operators should return a const object. However, all of the CERT recommendations have been removed from public view, and so their justification for the behavior of this check requires an account on their wiki to view. .SS cert\-dcl37\-c .sp The cert\-dcl37\-c check is an alias, please see \fI\%bugprone\-reserved\-identifier\fP for more information. .SS cert\-dcl50\-cpp .sp This check flags all function definitions (but not declarations) of C\-style variadic functions. .sp This check corresponds to the CERT C++ Coding Standard rule \fI\%DCL50\-CPP. Do not define a C\-style variadic function\fP\&. .SS cert\-dcl51\-cpp .sp The cert\-dcl51\-cpp check is an alias, please see \fI\%bugprone\-reserved\-identifier\fP for more information. .SS cert\-dcl54\-cpp .sp The cert\-dcl54\-cpp check is an alias, please see \fI\%misc\-new\-delete\-overloads\fP for more information. .SS cert\-dcl58\-cpp .sp Modification of the \fBstd\fP or \fBposix\fP namespace can result in undefined behavior. This check warns for such modifications. The \fBstd\fP (or \fBposix\fP) namespace is allowed to be extended with (class or function) template specializations that depend on an user\-defined type (a type that is not defined in the standard system headers). .sp The check detects the following (user provided) declarations in namespace \fBstd\fP or \fBposix\fP: .INDENT 0.0 .IP \(bu 2 Anything that is not a template specialization. .IP \(bu 2 Explicit specializations of any standard library function template or class template, if it does not have any user\-defined type as template argument. .IP \(bu 2 Explicit specializations of any member function of a standard library class template. .IP \(bu 2 Explicit specializations of any member function template of a standard library class or class template. .IP \(bu 2 Explicit or partial specialization of any member class template of a standard library class or class template. .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C namespace std { int x; // warning: modification of \(aqstd\(aq namespace can result in undefined behavior [cert\-dcl58\-cpp] } namespace posix::a { // warning: modification of \(aqposix\(aq namespace can result in undefined behavior } template <> struct ::std::hash { // warning: modification of \(aqstd\(aq namespace can result in undefined behavior unsigned long operator()(const long &K) const { return K; } }; struct MyData { long data; }; template <> struct ::std::hash { // no warning: specialization with user\-defined type unsigned long operator()(const MyData &K) const { return K.data; } }; namespace std { template <> void swap(bool &a, bool &b); // warning: modification of \(aqstd\(aq namespace can result in undefined behavior template <> bool less::operator()(MyData &&, MyData &&) const { // warning: modification of \(aqstd\(aq namespace can result in undefined behavior return true; } } .ft P .fi .UNINDENT .UNINDENT .sp This check corresponds to the CERT C++ Coding Standard rule \fI\%DCL58\-CPP. Do not modify the standard namespaces\fP\&. .SS cert\-dcl59\-cpp .sp The cert\-dcl59\-cpp check is an alias, please see \fI\%google\-build\-namespaces\fP for more information. .SS cert\-env33\-c .sp This check flags calls to \fBsystem()\fP, \fBpopen()\fP, and \fB_popen()\fP, which execute a command processor. It does not flag calls to \fBsystem()\fP with a null pointer argument, as such a call checks for the presence of a command processor but does not actually attempt to execute a command. .sp This check corresponds to the CERT C Coding Standard rule \fI\%ENV33\-C. Do not call system()\fP\&. .SS cert\-err09\-cpp .sp The cert\-err09\-cpp check is an alias, please see \fI\%misc\-throw\-by\-value\-catch\-by\-reference\fP for more information. .sp This check corresponds to the CERT C++ Coding Standard recommendation ERR09\-CPP. Throw anonymous temporaries. However, all of the CERT recommendations have been removed from public view, and so their justification for the behavior of this check requires an account on their wiki to view. .SS cert\-err33\-c .sp Warns on unused function return values. Many of the standard library functions return a value that indicates if the call was successful. Ignoring the returned value can cause unexpected behavior if an error has occurred. The following functions are checked: .INDENT 0.0 .IP \(bu 2 aligned_alloc() .IP \(bu 2 asctime_s() .IP \(bu 2 at_quick_exit() .IP \(bu 2 atexit() .IP \(bu 2 bsearch() .IP \(bu 2 bsearch_s() .IP \(bu 2 btowc() .IP \(bu 2 c16rtomb() .IP \(bu 2 c32rtomb() .IP \(bu 2 calloc() .IP \(bu 2 clock() .IP \(bu 2 cnd_broadcast() .IP \(bu 2 cnd_init() .IP \(bu 2 cnd_signal() .IP \(bu 2 cnd_timedwait() .IP \(bu 2 cnd_wait() .IP \(bu 2 ctime_s() .IP \(bu 2 fclose() .IP \(bu 2 fflush() .IP \(bu 2 fgetc() .IP \(bu 2 fgetpos() .IP \(bu 2 fgets() .IP \(bu 2 fgetwc() .IP \(bu 2 fopen() .IP \(bu 2 fopen_s() .IP \(bu 2 fprintf() .IP \(bu 2 fprintf_s() .IP \(bu 2 fputc() .IP \(bu 2 fputs() .IP \(bu 2 fputwc() .IP \(bu 2 fputws() .IP \(bu 2 fread() .IP \(bu 2 freopen() .IP \(bu 2 freopen_s() .IP \(bu 2 fscanf() .IP \(bu 2 fscanf_s() .IP \(bu 2 fseek() .IP \(bu 2 fsetpos() .IP \(bu 2 ftell() .IP \(bu 2 fwprintf() .IP \(bu 2 fwprintf_s() .IP \(bu 2 fwrite() .IP \(bu 2 fwscanf() .IP \(bu 2 fwscanf_s() .IP \(bu 2 getc() .IP \(bu 2 getchar() .IP \(bu 2 getenv() .IP \(bu 2 getenv_s() .IP \(bu 2 gets_s() .IP \(bu 2 getwc() .IP \(bu 2 getwchar() .IP \(bu 2 gmtime() .IP \(bu 2 gmtime_s() .IP \(bu 2 localtime() .IP \(bu 2 localtime_s() .IP \(bu 2 malloc() .IP \(bu 2 mbrtoc16() .IP \(bu 2 mbrtoc32() .IP \(bu 2 mbsrtowcs() .IP \(bu 2 mbsrtowcs_s() .IP \(bu 2 mbstowcs() .IP \(bu 2 mbstowcs_s() .IP \(bu 2 memchr() .IP \(bu 2 mktime() .IP \(bu 2 mtx_init() .IP \(bu 2 mtx_lock() .IP \(bu 2 mtx_timedlock() .IP \(bu 2 mtx_trylock() .IP \(bu 2 mtx_unlock() .IP \(bu 2 printf_s() .IP \(bu 2 putc() .IP \(bu 2 putwc() .IP \(bu 2 raise() .IP \(bu 2 realloc() .IP \(bu 2 remove() .IP \(bu 2 rename() .IP \(bu 2 setlocale() .IP \(bu 2 setvbuf() .IP \(bu 2 scanf() .IP \(bu 2 scanf_s() .IP \(bu 2 signal() .IP \(bu 2 snprintf() .IP \(bu 2 snprintf_s() .IP \(bu 2 sprintf() .IP \(bu 2 sprintf_s() .IP \(bu 2 sscanf() .IP \(bu 2 sscanf_s() .IP \(bu 2 strchr() .IP \(bu 2 strerror_s() .IP \(bu 2 strftime() .IP \(bu 2 strpbrk() .IP \(bu 2 strrchr() .IP \(bu 2 strstr() .IP \(bu 2 strtod() .IP \(bu 2 strtof() .IP \(bu 2 strtoimax() .IP \(bu 2 strtok() .IP \(bu 2 strtok_s() .IP \(bu 2 strtol() .IP \(bu 2 strtold() .IP \(bu 2 strtoll() .IP \(bu 2 strtoumax() .IP \(bu 2 strtoul() .IP \(bu 2 strtoull() .IP \(bu 2 strxfrm() .IP \(bu 2 swprintf() .IP \(bu 2 swprintf_s() .IP \(bu 2 swscanf() .IP \(bu 2 swscanf_s() .IP \(bu 2 thrd_create() .IP \(bu 2 thrd_detach() .IP \(bu 2 thrd_join() .IP \(bu 2 thrd_sleep() .IP \(bu 2 time() .IP \(bu 2 timespec_get() .IP \(bu 2 tmpfile() .IP \(bu 2 tmpfile_s() .IP \(bu 2 tmpnam() .IP \(bu 2 tmpnam_s() .IP \(bu 2 tss_create() .IP \(bu 2 tss_get() .IP \(bu 2 tss_set() .IP \(bu 2 ungetc() .IP \(bu 2 ungetwc() .IP \(bu 2 vfprintf() .IP \(bu 2 vfprintf_s() .IP \(bu 2 vfscanf() .IP \(bu 2 vfscanf_s() .IP \(bu 2 vfwprintf() .IP \(bu 2 vfwprintf_s() .IP \(bu 2 vfwscanf() .IP \(bu 2 vfwscanf_s() .IP \(bu 2 vprintf_s() .IP \(bu 2 vscanf() .IP \(bu 2 vscanf_s() .IP \(bu 2 vsnprintf() .IP \(bu 2 vsnprintf_s() .IP \(bu 2 vsprintf() .IP \(bu 2 vsprintf_s() .IP \(bu 2 vsscanf() .IP \(bu 2 vsscanf_s() .IP \(bu 2 vswprintf() .IP \(bu 2 vswprintf_s() .IP \(bu 2 vswscanf() .IP \(bu 2 vswscanf_s() .IP \(bu 2 vwprintf_s() .IP \(bu 2 vwscanf() .IP \(bu 2 vwscanf_s() .IP \(bu 2 wcrtomb() .IP \(bu 2 wcschr() .IP \(bu 2 wcsftime() .IP \(bu 2 wcspbrk() .IP \(bu 2 wcsrchr() .IP \(bu 2 wcsrtombs() .IP \(bu 2 wcsrtombs_s() .IP \(bu 2 wcsstr() .IP \(bu 2 wcstod() .IP \(bu 2 wcstof() .IP \(bu 2 wcstoimax() .IP \(bu 2 wcstok() .IP \(bu 2 wcstok_s() .IP \(bu 2 wcstol() .IP \(bu 2 wcstold() .IP \(bu 2 wcstoll() .IP \(bu 2 wcstombs() .IP \(bu 2 wcstombs_s() .IP \(bu 2 wcstoumax() .IP \(bu 2 wcstoul() .IP \(bu 2 wcstoull() .IP \(bu 2 wcsxfrm() .IP \(bu 2 wctob() .IP \(bu 2 wctrans() .IP \(bu 2 wctype() .IP \(bu 2 wmemchr() .IP \(bu 2 wprintf_s() .IP \(bu 2 wscanf() .IP \(bu 2 wscanf_s() .UNINDENT .sp This check is an alias of check \fI\%bugprone\-unused\-return\-value\fP with a fixed set of functions. .sp The check corresponds to a part of CERT C Coding Standard rule \fI\%ERR33\-C. Detect and handle standard library errors\fP\&. The list of checked functions is taken from the rule, with following exception: .INDENT 0.0 .IP \(bu 2 The check can not differentiate if a function is called with \fBNULL\fP argument. Therefore the following functions are not checked: \fBmblen\fP, \fBmbrlen\fP, \fBmbrtowc\fP, \fBmbtowc\fP, \fBwctomb\fP, \fBwctomb_s\fP .UNINDENT .SS cert\-err34\-c .sp This check flags calls to string\-to\-number conversion functions that do not verify the validity of the conversion, such as \fBatoi()\fP or \fBscanf()\fP\&. It does not flag calls to \fBstrtol()\fP, or other, related conversion functions that do perform better error checking. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include void func(const char *buff) { int si; if (buff) { si = atoi(buff); /* \(aqatoi\(aq used to convert a string to an integer, but function will not report conversion errors; consider using \(aqstrtol\(aq instead. */ } else { /* Handle error */ } } .ft P .fi .UNINDENT .UNINDENT .sp This check corresponds to the CERT C Coding Standard rule \fI\%ERR34\-C. Detect errors when converting a string to a number\fP\&. .SS cert\-err52\-cpp .sp This check flags all call expressions involving \fBsetjmp()\fP and \fBlongjmp()\fP\&. .sp This check corresponds to the CERT C++ Coding Standard rule \fI\%ERR52\-CPP. Do not use setjmp() or longjmp()\fP\&. .SS cert\-err58\-cpp .sp This check flags all \fBstatic\fP or \fBthread_local\fP variable declarations where the initializer for the object may throw an exception. .sp This check corresponds to the CERT C++ Coding Standard rule \fI\%ERR58\-CPP. Handle all exceptions thrown before main() begins executing\fP\&. .SS cert\-err60\-cpp .sp This check flags all throw expressions where the exception object is not nothrow copy constructible. .sp This check corresponds to the CERT C++ Coding Standard rule \fI\%ERR60\-CPP. Exception objects must be nothrow copy constructible\fP\&. .SS cert\-err61\-cpp .sp The cert\-err61\-cpp check is an alias, please see \fI\%misc\-throw\-by\-value\-catch\-by\-reference\fP for more information. .SS cert\-exp42\-c .sp The cert\-exp42\-c check is an alias, please see \fI\%bugprone\-suspicious\-memory\-comparison\fP for more information. .SS cert\-fio38\-c .sp The cert\-fio38\-c check is an alias, please see \fI\%misc\-non\-copyable\-objects\fP for more information. .SS cert\-flp30\-c .sp This check flags \fBfor\fP loops where the induction expression has a floating\-point type. .sp This check corresponds to the CERT C Coding Standard rule \fI\%FLP30\-C. Do not use floating\-point variables as loop counters\fP\&. .SS cert\-flp37\-c .sp The cert\-flp37\-c check is an alias, please see \fI\%bugprone\-suspicious\-memory\-comparison\fP for more information. .SS cert\-mem57\-cpp .sp This check flags uses of default \fBoperator new\fP where the type has extended alignment (an alignment greater than the fundamental alignment). (The default \fBoperator new\fP is guaranteed to provide the correct alignment if the requested alignment is less or equal to the fundamental alignment). Only cases are detected (by design) where the \fBoperator new\fP is not user\-defined and is not a placement new (the reason is that in these cases we assume that the user provided the correct memory allocation). .sp This check corresponds to the CERT C++ Coding Standard rule \fI\%MEM57\-CPP. Avoid using default operator new for over\-aligned types\fP\&. .SS cert\-msc24\-c .sp The cert\-msc24\-c check is an alias, please see \fI\%bugprone\-unsafe\-functions\fP for more information. .SS cert\-msc30\-c .sp The cert\-msc30\-c check is an alias, please see \fI\%cert\-msc50\-cpp\fP for more information. .SS cert\-msc32\-c .sp The cert\-msc32\-c check is an alias, please see \fI\%cert\-msc51\-cpp\fP for more information. .SS cert\-msc33\-c .sp The cert\-msc33\-c check is an alias, please see \fI\%bugprone\-unsafe\-functions\fP for more information. .SS cert\-msc50\-cpp .sp Pseudorandom number generators use mathematical algorithms to produce a sequence of numbers with good statistical properties, but the numbers produced are not genuinely random. The \fBstd::rand()\fP function takes a seed (number), runs a mathematical operation on it and returns the result. By manipulating the seed the result can be predictable. This check warns for the usage of \fBstd::rand()\fP\&. .SS cert\-msc51\-cpp .sp This check flags all pseudo\-random number engines, engine adaptor instantiations and \fBsrand()\fP when initialized or seeded with default argument, constant expression or any user\-configurable type. Pseudo\-random number engines seeded with a predictable value may cause vulnerabilities e.g. in security protocols. This is a CERT security rule, see \fI\%MSC51\-CPP. Ensure your random number generator is properly seeded\fP and \fI\%MSC32\-C. Properly seed pseudorandom number generators\fP\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo() { std::mt19937 engine1; // Diagnose, always generate the same sequence std::mt19937 engine2(1); // Diagnose engine1.seed(); // Diagnose engine2.seed(1); // Diagnose std::time_t t; engine1.seed(std::time(&t)); // Diagnose, system time might be controlled by user int x = atoi(argv[1]); std::mt19937 engine3(x); // Will not warn } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B DisallowedSeedTypes A comma\-separated list of the type names which are disallowed. Default values are \fBtime_t\fP, \fBstd::time_t\fP\&. .UNINDENT .SS cert\-msc54\-cpp .sp The cert\-msc54\-cpp check is an alias, please see \fI\%bugprone\-signal\-handler\fP for more information. .SS cert\-oop11\-cpp .sp The cert\-oop11\-cpp check is an alias, please see \fI\%performance\-move\-constructor\-init\fP for more information. .sp This check corresponds to the CERT C++ Coding Standard recommendation OOP11\-CPP. Do not copy\-initialize members or base classes from a move constructor. However, all of the CERT recommendations have been removed from public view, and so their justification for the behavior of this check requires an account on their wiki to view. .SS cert\-oop54\-cpp .sp The cert\-oop54\-cpp check is an alias, please see \fI\%bugprone\-unhandled\-self\-assignment\fP for more information. .SS cert\-oop57\-cpp .INDENT 0.0 .INDENT 3.5 Flags use of the \fIC\fP standard library functions \fBmemset\fP, \fBmemcpy\fP and \fBmemcmp\fP and similar derivatives on non\-trivial types. .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B MemSetNames Specify extra functions to flag that act similarly to \fBmemset\fP\&. Specify names in a semicolon delimited list. Default is an empty string. The check will detect the following functions: \fImemset\fP, \fIstd::memset\fP\&. .UNINDENT .INDENT 0.0 .TP .B MemCpyNames Specify extra functions to flag that act similarly to \fBmemcpy\fP\&. Specify names in a semicolon delimited list. Default is an empty string. The check will detect the following functions: \fIstd::memcpy\fP, \fImemcpy\fP, \fIstd::memmove\fP, \fImemmove\fP, \fIstd::strcpy\fP, \fIstrcpy\fP, \fImemccpy\fP, \fIstpncpy\fP, \fIstrncpy\fP\&. .UNINDENT .INDENT 0.0 .TP .B MemCmpNames Specify extra functions to flag that act similarly to \fBmemcmp\fP\&. Specify names in a semicolon delimited list. Default is an empty string. The check will detect the following functions: \fIstd::memcmp\fP, \fImemcmp\fP, \fIstd::strcmp\fP, \fIstrcmp\fP, \fIstrncmp\fP\&. .UNINDENT .sp This check corresponds to the CERT C++ Coding Standard rule \fI\%OOP57\-CPP. Prefer special member functions and overloaded operators to C Standard Library functions\fP\&. .SS cert\-oop58\-cpp .sp Finds assignments to the copied object and its direct or indirect members in copy constructors and copy assignment operators. .sp This check corresponds to the CERT C Coding Standard rule \fI\%OOP58\-CPP. Copy operations must not mutate the source object\fP\&. .SS cert\-pos44\-c .sp The cert\-pos44\-c check is an alias, please see \fI\%bugprone\-bad\-signal\-to\-kill\-thread\fP for more information. .SS cert\-pos47\-c .sp The cert\-pos47\-c check is an alias, please see \fI\%concurrency\-thread\-canceltype\-asynchronous\fP for more information. .SS cert\-sig30\-c .sp The cert\-sig30\-c check is an alias, please see \fI\%bugprone\-signal\-handler\fP for more information. .SS cert\-str34\-c .sp The cert\-str34\-c check is an alias, please see \fI\%bugprone\-signed\-char\-misuse\fP for more information. .SS clang\-analyzer\-core.CallAndMessage .sp The clang\-analyzer\-core.CallAndMessage check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-core.DivideZero .sp The clang\-analyzer\-core.DivideZero check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-core.DynamicTypePropagation .sp Generate dynamic type information .SS clang\-analyzer\-core.NonNullParamChecker .sp The clang\-analyzer\-core.NonNullParamChecker check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-core.NullDereference .sp The clang\-analyzer\-core.NullDereference check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-core.StackAddressEscape .sp The clang\-analyzer\-core.StackAddressEscape check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-core.UndefinedBinaryOperatorResult .sp The clang\-analyzer\-core.UndefinedBinaryOperatorResult check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-core.VLASize .sp The clang\-analyzer\-core.VLASize check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-core.uninitialized.ArraySubscript .sp The clang\-analyzer\-core.uninitialized.ArraySubscript check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-core.uninitialized.Assign .sp The clang\-analyzer\-core.uninitialized.Assign check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-core.uninitialized.Branch .sp The clang\-analyzer\-core.uninitialized.Branch check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-core.uninitialized.CapturedBlockVariable .sp Check for blocks that capture uninitialized values .SS clang\-analyzer\-core.uninitialized.UndefReturn .sp The clang\-analyzer\-core.uninitialized.UndefReturn check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-cplusplus.InnerPointer .sp Check for inner pointers of C++ containers used after re/deallocation .SS clang\-analyzer\-cplusplus.Move .sp The clang\-analyzer\-cplusplus.Move check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-cplusplus.NewDelete .sp The clang\-analyzer\-cplusplus.NewDelete check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-cplusplus.NewDeleteLeaks .sp The clang\-analyzer\-cplusplus.NewDeleteLeaks check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-deadcode.DeadStores .sp The clang\-analyzer\-deadcode.DeadStores check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-nullability.NullPassedToNonnull .sp The clang\-analyzer\-nullability.NullPassedToNonnull check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-nullability.NullReturnedFromNonnull .sp The clang\-analyzer\-nullability.NullReturnedFromNonnull check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-nullability.NullableDereferenced .sp The clang\-analyzer\-nullability.NullableDereferenced check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-nullability.NullablePassedToNonnull .sp The clang\-analyzer\-nullability.NullablePassedToNonnull check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-nullability.NullableReturnedFromNonnull .sp Warns when a nullable pointer is returned from a function that has _Nonnull return type. .SS clang\-analyzer\-optin.cplusplus.UninitializedObject .sp The clang\-analyzer\-optin.cplusplus.UninitializedObject check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-optin.cplusplus.VirtualCall .sp The clang\-analyzer\-optin.cplusplus.VirtualCall check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-optin.mpi.MPI\-Checker .sp The clang\-analyzer\-optin.mpi.MPI\-Checker check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-optin.osx.OSObjectCStyleCast .sp Checker for C\-style casts of OSObjects .SS clang\-analyzer\-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker .sp The clang\-analyzer\-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-optin.osx.cocoa.localizability.NonLocalizedStringChecker .sp The clang\-analyzer\-optin.osx.cocoa.localizability.NonLocalizedStringChecker check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-optin.performance.GCDAntipattern .sp Check for performance anti\-patterns when using Grand Central Dispatch .SS clang\-analyzer\-optin.performance.Padding .sp Check for excessively padded structs. .SS clang\-analyzer\-optin.portability.UnixAPI .sp Finds implementation\-defined behavior in UNIX/Posix functions .SS clang\-analyzer\-osx.API .sp The clang\-analyzer\-osx.API check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.MIG .sp Find violations of the Mach Interface Generator calling convention .SS clang\-analyzer\-osx.NumberObjectConversion .sp Check for erroneous conversions of objects representing numbers into numbers .SS clang\-analyzer\-osx.OSObjectRetainCount .sp Check for leaks and improper reference count management for OSObject .SS clang\-analyzer\-osx.ObjCProperty .sp Check for proper uses of Objective\-C properties .SS clang\-analyzer\-osx.SecKeychainAPI .sp The clang\-analyzer\-osx.SecKeychainAPI check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.cocoa.AtSync .sp The clang\-analyzer\-osx.cocoa.AtSync check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.cocoa.AutoreleaseWrite .sp Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective\-C .SS clang\-analyzer\-osx.cocoa.ClassRelease .sp The clang\-analyzer\-osx.cocoa.ClassRelease check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.cocoa.Dealloc .sp The clang\-analyzer\-osx.cocoa.Dealloc check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.cocoa.IncompatibleMethodTypes .sp The clang\-analyzer\-osx.cocoa.IncompatibleMethodTypes check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.cocoa.Loops .sp Improved modeling of loops using Cocoa collection types .SS clang\-analyzer\-osx.cocoa.MissingSuperCall .sp Warn about Objective\-C methods that lack a necessary call to super .SS clang\-analyzer\-osx.cocoa.NSAutoreleasePool .sp The clang\-analyzer\-osx.cocoa.NSAutoreleasePool check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.cocoa.NSError .sp The clang\-analyzer\-osx.cocoa.NSError check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.cocoa.NilArg .sp The clang\-analyzer\-osx.cocoa.NilArg check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.cocoa.NonNilReturnValue .sp Model the APIs that are guaranteed to return a non\-nil value .SS clang\-analyzer\-osx.cocoa.ObjCGenerics .sp The clang\-analyzer\-osx.cocoa.ObjCGenerics check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.cocoa.RetainCount .sp The clang\-analyzer\-osx.cocoa.RetainCount check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.cocoa.RunLoopAutoreleaseLeak .sp Check for leaked memory in autorelease pools that will never be drained .SS clang\-analyzer\-osx.cocoa.SelfInit .sp The clang\-analyzer\-osx.cocoa.SelfInit check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.cocoa.SuperDealloc .sp The clang\-analyzer\-osx.cocoa.SuperDealloc check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.cocoa.UnusedIvars .sp The clang\-analyzer\-osx.cocoa.UnusedIvars check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.cocoa.VariadicMethodTypes .sp The clang\-analyzer\-osx.cocoa.VariadicMethodTypes check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.coreFoundation.CFError .sp The clang\-analyzer\-osx.coreFoundation.CFError check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.coreFoundation.CFNumber .sp The clang\-analyzer\-osx.coreFoundation.CFNumber check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.coreFoundation.CFRetainRelease .sp The clang\-analyzer\-osx.coreFoundation.CFRetainRelease check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.coreFoundation.containers.OutOfBounds .sp The clang\-analyzer\-osx.coreFoundation.containers.OutOfBounds check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-osx.coreFoundation.containers.PointerSizedValues .sp The clang\-analyzer\-osx.coreFoundation.containers.PointerSizedValues check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-security.FloatLoopCounter .sp The clang\-analyzer\-security.FloatLoopCounter check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-security.insecureAPI.DeprecatedOrUnsafeBufferHandling .sp The clang\-analyzer\-security.insecureAPI.DeprecatedOrUnsafeBufferHandling check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-security.insecureAPI.UncheckedReturn .sp The clang\-analyzer\-security.insecureAPI.UncheckedReturn check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-security.insecureAPI.bcmp .sp The clang\-analyzer\-security.insecureAPI.bcmp check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-security.insecureAPI.bcopy .sp The clang\-analyzer\-security.insecureAPI.bcopy check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-security.insecureAPI.bzero .sp The clang\-analyzer\-security.insecureAPI.bzero check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-security.insecureAPI.getpw .sp The clang\-analyzer\-security.insecureAPI.getpw check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-security.insecureAPI.gets .sp The clang\-analyzer\-security.insecureAPI.gets check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-security.insecureAPI.mkstemp .sp The clang\-analyzer\-security.insecureAPI.mkstemp check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-security.insecureAPI.mktemp .sp The clang\-analyzer\-security.insecureAPI.mktemp check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-security.insecureAPI.rand .sp The clang\-analyzer\-security.insecureAPI.rand check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-security.insecureAPI.strcpy .sp The clang\-analyzer\-security.insecureAPI.strcpy check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-security.insecureAPI.vfork .sp The clang\-analyzer\-security.insecureAPI.vfork check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-unix.API .sp The clang\-analyzer\-unix.API check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-unix.Malloc .sp The clang\-analyzer\-unix.Malloc check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-unix.MallocSizeof .sp The clang\-analyzer\-unix.MallocSizeof check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-unix.MismatchedDeallocator .sp The clang\-analyzer\-unix.MismatchedDeallocator check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-unix.Vfork .sp The clang\-analyzer\-unix.Vfork check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-unix.cstring.BadSizeArg .sp The clang\-analyzer\-unix.cstring.BadSizeArg check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-unix.cstring.NullArg .sp The clang\-analyzer\-unix.cstring.NullArg check is an alias, please see \fI\%Clang Static Analyzer Available Checkers\fP for more information. .SS clang\-analyzer\-valist.CopyToSelf .sp Check for va_lists which are copied onto itself. .SS clang\-analyzer\-valist.Uninitialized .sp Check for usages of uninitialized (or already released) va_lists. .SS clang\-analyzer\-valist.Unterminated .sp Check for va_lists which are not released by a va_end call. .SS concurrency\-mt\-unsafe .sp Checks for some thread\-unsafe functions against a black list of known\-to\-be\-unsafe functions. Usually they access static variables without synchronization (e.g. gmtime(3)) or utilize signals in a racy way. The set of functions to check is specified with the \fIFunctionSet\fP option. .sp Note that using some thread\-unsafe functions may be still valid in concurrent programming if only a single thread is used (e.g. setenv(3)), however, some functions may track a state in global variables which would be clobbered by subsequent (non\-parallel, but concurrent) calls to a related function. E.g. the following code suffers from unprotected accesses to a global state: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // getnetent(3) maintains global state with DB connection, etc. // If a concurrent green thread calls getnetent(3), the global state is corrupted. netent = getnetent(); yield(); netent = getnetent(); .ft P .fi .UNINDENT .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C tm = gmtime(timep); // uses a global buffer sleep(1); // implementation may use SIGALRM .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B FunctionSet Specifies which functions in libc should be considered thread\-safe, possible values are \fIposix\fP, \fIglibc\fP, or \fIany\fP\&. .sp \fIposix\fP means POSIX defined thread\-unsafe functions. POSIX.1\-2001 in \(dq2.9.1 Thread\-Safety\(dq defines that all functions specified in the standard are thread\-safe except a predefined list of thread\-unsafe functions. .sp Glibc defines some of them as thread\-safe (e.g. dirname(3)), but adds non\-POSIX thread\-unsafe ones (e.g. getopt_long(3)). Glibc\(aqs list is compiled from GNU web documentation with a search for MT\-Safe tag: \fI\%https://www.gnu.org/software/libc/manual/html_node/POSIX\-Safety\-Concepts.html\fP .sp If you want to identify thread\-unsafe API for at least one libc or unsure which libc will be used, use \fIany\fP (default). .UNINDENT .SS concurrency\-thread\-canceltype\-asynchronous .sp Finds \fBpthread_setcanceltype\fP function calls where a thread\(aqs cancellation type is set to asynchronous. Asynchronous cancellation type (\fBPTHREAD_CANCEL_ASYNCHRONOUS\fP) is generally unsafe, use type \fBPTHREAD_CANCEL_DEFERRED\fP instead which is the default. Even with deferred cancellation, a cancellation point in an asynchronous signal handler may still be acted upon and the effect is as if it was an asynchronous cancellation. .sp This check corresponds to the CERT C Coding Standard rule \fI\%POS47\-C. Do not use threads that can be canceled asynchronously\fP\&. .SS cppcoreguidelines\-avoid\-c\-arrays .sp The cppcoreguidelines\-avoid\-c\-arrays check is an alias, please see \fI\%modernize\-avoid\-c\-arrays\fP for more information. .SS cppcoreguidelines\-avoid\-capturing\-lambda\-coroutines .sp Flags C++20 coroutine lambdas with non\-empty capture lists that may cause use\-after\-free errors and suggests avoiding captures or ensuring the lambda closure object has a guaranteed lifetime. .sp This check implements \fI\%CP.51\fP from the C++ Core Guidelines. .sp Using coroutine lambdas with non\-empty capture lists can be risky, as capturing variables can lead to accessing freed memory after the first suspension point. This issue can occur even with refcounted smart pointers and copyable types. When a lambda expression creates a coroutine, it results in a closure object with storage, which is often on the stack and will eventually go out of scope. When the closure object goes out of scope, its captures also go out of scope. While normal lambdas finish executing before this happens, coroutine lambdas may resume from suspension after the closure object has been destructed, resulting in use\-after\-free memory access for all captures. .sp Consider the following example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int value = get_value(); std::shared_ptr sharedFoo = get_foo(); { const auto lambda = [value, sharedFoo]() \-> std::future { co_await something(); // \(dqsharedFoo\(dq and \(dqvalue\(dq have already been destroyed // the \(dqshared\(dq pointer didn\(aqt accomplish anything }; lambda(); } // the lambda closure object has now gone out of scope .ft P .fi .UNINDENT .UNINDENT .sp In this example, the lambda object is defined with two captures: value and \fBsharedFoo\fP\&. When \fBlambda()\fP is called, the lambda object is created on the stack, and the captures are copied into the closure object. When the coroutine is suspended, the lambda object goes out of scope, and the closure object is destroyed. When the coroutine is resumed, the captured variables may have been destroyed, resulting in use\-after\-free bugs. .sp In conclusion, the use of coroutine lambdas with non\-empty capture lists can lead to use\-after\-free errors when resuming the coroutine after the closure object has been destroyed. This check helps prevent such errors by flagging C++20 coroutine lambdas with non\-empty capture lists and suggesting avoiding captures or ensuring the lambda closure object has a guaranteed lifetime. .sp Following these guidelines can help ensure the safe and reliable use of coroutine lambdas in C++ code. .SS cppcoreguidelines\-avoid\-const\-or\-ref\-data\-members .sp This check warns when structs or classes that are copyable or movable, and have const\-qualified or reference (lvalue or rvalue) data members. Having such members is rarely useful, and makes the class only copy\-constructible but not copy\-assignable. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Bad, const\-qualified member struct Const { const int x; } // Good: class Foo { public: int get() const { return x; } private: int x; }; // Bad, lvalue reference member struct Ref { int& x; }; // Good: struct Foo { int* x; std::unique_ptr x; std::shared_ptr x; gsl::not_null x; }; // Bad, rvalue reference member struct RefRef { int&& x; }; .ft P .fi .UNINDENT .UNINDENT .sp This check implements \fI\%C.12\fP from the C++ Core Guidelines. .sp Further reading: \fI\%Data members: Never const\fP\&. .SS cppcoreguidelines\-avoid\-do\-while .sp Warns when using \fBdo\-while\fP loops. They are less readable than plain \fBwhile\fP loops, since the termination condition is at the end and the condition is not checked prior to the first iteration. This can lead to subtle bugs. .sp This check implements \fI\%ES.75\fP from the C++ Core Guidelines. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int x; do { std::cin >> x; // ... } while (x < 0); .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreMacros Ignore the check when analyzing macros. This is useful for safely defining function\-like macros: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C #define FOO_BAR(x) \e do { \e foo(x); \e bar(x); \e } while(0) .ft P .fi .UNINDENT .UNINDENT .sp Defaults to \fIfalse\fP\&. .UNINDENT .SS cppcoreguidelines\-avoid\-goto .sp The usage of \fBgoto\fP for control flow is error prone and should be replaced with looping constructs. Only forward jumps in nested loops are accepted. .sp This check implements \fI\%ES.76\fP from the C++ Core Guidelines and \fI\%6.3.1\fP from High Integrity C++ Coding Standard. .sp For more information on why to avoid programming with \fBgoto\fP you can read the famous paper \fI\%A Case against the GO TO Statement.\fP\&. .sp The check diagnoses \fBgoto\fP for backward jumps in every language mode. These should be replaced with \fIC/C++\fP looping constructs. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Bad, handwritten for loop. int i = 0; // Jump label for the loop loop_start: do_some_operation(); if (i < 100) { ++i; goto loop_start; } // Better for(int i = 0; i < 100; ++i) do_some_operation(); .ft P .fi .UNINDENT .UNINDENT .sp Modern C++ needs \fBgoto\fP only to jump out of nested loops. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C for(int i = 0; i < 100; ++i) { for(int j = 0; j < 100; ++j) { if (i * j > 500) goto early_exit; } } early_exit: some_operation(); .ft P .fi .UNINDENT .UNINDENT .sp All other uses of \fBgoto\fP are diagnosed in \fIC++\fP\&. .SS cppcoreguidelines\-avoid\-magic\-numbers .sp The cppcoreguidelines\-avoid\-magic\-numbers check is an alias, please see \fI\%readability\-magic\-numbers\fP for more information. .SS cppcoreguidelines\-avoid\-non\-const\-global\-variables .sp Finds non\-const global variables as described in \fI\%I.2\fP of C++ Core Guidelines. As \fI\%R.6\fP of C++ Core Guidelines is a duplicate of rule \fI\%I.2\fP it also covers that rule. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C char a; // Warns! const char b = 0; namespace some_namespace { char c; // Warns! const char d = 0; } char * c_ptr1 = &some_namespace::c; // Warns! char *const c_const_ptr = &some_namespace::c; // Warns! char & c_reference = some_namespace::c; // Warns! class Foo // No Warnings inside Foo, only namespace scope is covered { public: char e = 0; const char f = 0; protected: char g = 0; private: char h = 0; }; .ft P .fi .UNINDENT .UNINDENT .sp The variables \fBa\fP, \fBc\fP, \fBc_ptr1\fP, \fBc_const_ptr\fP and \fBc_reference\fP will all generate warnings since they are either a non\-const globally accessible variable, a pointer or a reference providing global access to non\-const data or both. .SS cppcoreguidelines\-avoid\-reference\-coroutine\-parameters .sp Warns when a coroutine accepts reference parameters. After a coroutine suspend point, references could be dangling and no longer valid. Instead, pass parameters as values. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::future someCoroutine(int& val) { co_await ...; // When the coroutine is resumed, \(aqval\(aq might no longer be valid. if (val) ... } .ft P .fi .UNINDENT .UNINDENT .sp This check implements \fI\%CP.53\fP from the C++ Core Guidelines. .SS cppcoreguidelines\-c\-copy\-assignment\-signature .sp The cppcoreguidelines\-c\-copy\-assignment\-signature check is an alias, please see \fI\%misc\-unconventional\-assign\-operator\fP for more information. .SS cppcoreguidelines\-explicit\-virtual\-functions .sp The cppcoreguidelines\-explicit\-virtual\-functions check is an alias, please see \fI\%modernize\-use\-override\fP for more information. .SS cppcoreguidelines\-init\-variables .sp Checks whether there are local variables that are declared without an initial value. These may lead to unexpected behavior if there is a code path that reads the variable before assigning to it. .sp This rule is part of the \fI\%Type safety (Type.5)\fP profile and \fI\%ES.20\fP from the C++ Core Guidelines. .sp Only integers, booleans, floats, doubles and pointers are checked. The fix option initializes all detected values with the value of zero. An exception is float and double types, which are initialized to NaN. .sp As an example a function that looks like this: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void function() { int x; char *txt; double d; // Rest of the function. } .ft P .fi .UNINDENT .UNINDENT .sp Would be rewritten to look like this: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include void function() { int x = 0; char *txt = nullptr; double d = NAN; // Rest of the function. } .ft P .fi .UNINDENT .UNINDENT .sp It warns for the uninitialized enum case, but without a FixIt: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C enum A {A1, A2, A3}; enum A_c : char { A_c1, A_c2, A_c3 }; enum class B { B1, B2, B3 }; enum class B_i : int { B_i1, B_i2, B_i3 }; void function() { A a; // Warning: variable \(aqa\(aq is not initialized A_c a_c; // Warning: variable \(aqa_c\(aq is not initialized B b; // Warning: variable \(aqb\(aq is not initialized B_i b_i; // Warning: variable \(aqb_i\(aq is not initialized } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B MathHeader A string specifying the header to include to get the definition of \fINAN\fP\&. Default is \fI\fP\&. .UNINDENT .SS cppcoreguidelines\-interfaces\-global\-init .sp This check flags initializers of globals that access extern objects, and therefore can lead to order\-of\-initialization problems. .sp This check implements \fI\%I.22\fP from the C++ Core Guidelines. .sp Note that currently this does not flag calls to non\-constexpr functions, and therefore globals could still be accessed from functions themselves. .SS cppcoreguidelines\-macro\-to\-enum .sp The cppcoreguidelines\-macro\-to\-enum check is an alias, please see \fI\%modernize\-macro\-to\-enum\fP for more information. .SS cppcoreguidelines\-macro\-usage .sp Finds macro usage that is considered problematic because better language constructs exist for the task. .sp The relevant sections in the C++ Core Guidelines are \fI\%ES.31\fP, and \fI\%ES.32\fP\&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #define C 0 #define F1(x, y) ((a) > (b) ? (a) : (b)) #define F2(...) (__VA_ARGS__) #define COMMA , #define NORETURN [[noreturn]] #define DEPRECATED attribute((deprecated)) #if LIB_EXPORTS #define DLLEXPORTS __declspec(dllexport) #else #define DLLEXPORTS __declspec(dllimport) #endif .ft P .fi .UNINDENT .UNINDENT .sp results in the following warnings: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C 4 warnings generated. test.cpp:1:9: warning: macro \(aqC\(aq used to declare a constant; consider using a \(aqconstexpr\(aq constant [cppcoreguidelines\-macro\-usage] #define C 0 ^ test.cpp:2:9: warning: function\-like macro \(aqF1\(aq used; consider a \(aqconstexpr\(aq template function [cppcoreguidelines\-macro\-usage] #define F1(x, y) ((a) > (b) ? (a) : (b)) ^ test.cpp:3:9: warning: variadic macro \(aqF2\(aq used; consider using a \(aqconstexpr\(aq variadic template function [cppcoreguidelines\-macro\-usage] #define F2(...) (__VA_ARGS__) ^ .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B AllowedRegexp A regular expression to filter allowed macros. For example \fIDEBUG*|LIBTORRENT*|TORRENT*|UNI*\fP could be applied to filter \fIlibtorrent\fP\&. Default value is \fI^DEBUG_*\fP\&. .UNINDENT .INDENT 0.0 .TP .B CheckCapsOnly Boolean flag to warn on all macros except those with CAPS_ONLY names. This option is intended to ease introduction of this check into older code bases. Default value is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreCommandLineMacros Boolean flag to toggle ignoring command\-line\-defined macros. Default value is \fItrue\fP\&. .UNINDENT .SS cppcoreguidelines\-misleading\-capture\-default\-by\-value .sp Warns when lambda specify a by\-value capture default and capture \fBthis\fP\&. .sp By\-value capture defaults in member functions can be misleading about whether data members are captured by value or reference. This occurs because specifying the capture default \fB[=]\fP actually captures the \fBthis\fP pointer by value, not the data members themselves. As a result, data members are still indirectly accessed via the captured \fBthis\fP pointer, which essentially means they are being accessed by reference. Therefore, even when using \fB[=]\fP, data members are effectively captured by reference, which might not align with the user\(aqs expectations. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct AClass { int member; void misleadingLogic() { int local = 0; member = 0; auto f = [=]() mutable { local += 1; member += 1; }; f(); // Here, local is 0 but member is 1 } void clearLogic() { int local = 0; member = 0; auto f = [this, local]() mutable { local += 1; member += 1; }; f(); // Here, local is 0 but member is 1 } }; .ft P .fi .UNINDENT .UNINDENT .sp This check implements \fI\%F.54\fP from the C++ Core Guidelines. .SS cppcoreguidelines\-missing\-std\-forward .sp Warns when a forwarding reference parameter is not forwarded inside the function body. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C template void wrapper(T&& t) { impl(std::forward(t), 1, 2); // Correct } template void wrapper2(T&& t) { impl(t, 1, 2); // Oops \- should use std::forward(t) } template void wrapper3(T&& t) { impl(std::move(t), 1, 2); // Also buggy \- should use std::forward(t) } template void wrapper_function(F&& f) { std::forward(f)(1, 2); // Correct } template void wrapper_function2(F&& f) { f(1, 2); // Incorrect \- may not invoke the desired qualified function operator } .ft P .fi .UNINDENT .UNINDENT .sp This check implements \fI\%F.19\fP from the C++ Core Guidelines. .SS cppcoreguidelines\-narrowing\-conversions .sp Checks for silent narrowing conversions, e.g: \fBint i = 0; i += 0.1;\fP\&. While the issue is obvious in this former example, it might not be so in the following: \fBvoid MyClass::f(double d) { int_member_ += d; }\fP\&. .sp This check implements \fI\%ES.46\fP from the C++ Core Guidelines. .INDENT 0.0 .TP .B We enforce only part of the guideline, more specifically, we flag narrowing conversions from: .INDENT 7.0 .IP \(bu 2 an integer to a narrower integer (e.g. \fBchar\fP to \fBunsigned char\fP) if WarnOnIntegerNarrowingConversion Option is set, .IP \(bu 2 an integer to a narrower floating\-point (e.g. \fBuint64_t\fP to \fBfloat\fP) if WarnOnIntegerToFloatingPointNarrowingConversion Option is set, .IP \(bu 2 a floating\-point to an integer (e.g. \fBdouble\fP to \fBint\fP), .IP \(bu 2 a floating\-point to a narrower floating\-point (e.g. \fBdouble\fP to \fBfloat\fP) if WarnOnFloatingPointNarrowingConversion Option is set. .UNINDENT .TP .B This check will flag: .INDENT 7.0 .IP \(bu 2 All narrowing conversions that are not marked by an explicit cast (c\-style or \fBstatic_cast\fP). For example: \fBint i = 0; i += 0.1;\fP, \fBvoid f(int); f(0.1);\fP, .IP \(bu 2 All applications of binary operators with a narrowing conversions. For example: \fBint i; i+= 0.1;\fP\&. .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B WarnOnIntegerNarrowingConversion When \fItrue\fP, the check will warn on narrowing integer conversion (e.g. \fBint\fP to \fBsize_t\fP). \fItrue\fP by default. .UNINDENT .INDENT 0.0 .TP .B WarnOnIntegerToFloatingPointNarrowingConversion When \fItrue\fP, the check will warn on narrowing integer to floating\-point conversion (e.g. \fBsize_t\fP to \fBdouble\fP). \fItrue\fP by default. .UNINDENT .INDENT 0.0 .TP .B WarnOnFloatingPointNarrowingConversion When \fItrue\fP, the check will warn on narrowing floating point conversion (e.g. \fBdouble\fP to \fBfloat\fP). \fItrue\fP by default. .UNINDENT .INDENT 0.0 .TP .B WarnWithinTemplateInstantiation When \fItrue\fP, the check will warn on narrowing conversions within template instantiations. \fIfalse\fP by default. .UNINDENT .INDENT 0.0 .TP .B WarnOnEquivalentBitWidth When \fItrue\fP, the check will warn on narrowing conversions that arise from casting between types of equivalent bit width. (e.g. \fIint n = uint(0);\fP or \fIlong long n = double(0);\fP) \fItrue\fP by default. .UNINDENT .INDENT 0.0 .TP .B IgnoreConversionFromTypes Narrowing conversions from any type in this semicolon\-separated list will be ignored. This may be useful to weed out commonly occurring, but less commonly problematic assignments such as \fIint n = std::vector().size();\fP or \fIint n = std::difference(it1, it2);\fP\&. The default list is empty, but one suggested list for a legacy codebase would be \fIsize_t;ptrdiff_t;size_type;difference_type\fP\&. .UNINDENT .INDENT 0.0 .TP .B PedanticMode When \fItrue\fP, the check will warn on assigning a floating point constant to an integer value even if the floating point value is exactly representable in the destination type (e.g. \fBint i = 1.0;\fP). \fIfalse\fP by default. .UNINDENT .SS FAQ .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 What does \(dqnarrowing conversion from \(aqint\(aq to \(aqfloat\(aq\(dq mean? .UNINDENT .UNINDENT .UNINDENT .sp An IEEE754 Floating Point number can represent all integer values in the range [\-2^PrecisionBits, 2^PrecisionBits] where PrecisionBits is the number of bits in the mantissa. .sp For \fBfloat\fP this would be [\-2^23, 2^23], where \fBint\fP can represent values in the range [\-2^31, 2^31\-1]. .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 What does \(dqimplementation\-defined\(dq mean? .UNINDENT .UNINDENT .UNINDENT .sp You may have encountered messages like \(dqnarrowing conversion from \(aqunsigned int\(aq to signed type \(aqint\(aq is implementation\-defined\(dq. The C/C++ standard does not mandate two\(aqs complement for signed integers, and so the compiler is free to define what the semantics are for converting an unsigned integer to signed integer. Clang\(aqs implementation uses the two\(aqs complement format. .SS cppcoreguidelines\-no\-malloc .sp This check handles C\-Style memory management using \fBmalloc()\fP, \fBrealloc()\fP, \fBcalloc()\fP and \fBfree()\fP\&. It warns about its use and tries to suggest the use of an appropriate RAII object. Furthermore, it can be configured to check against a user\-specified list of functions that are used for memory management (e.g. \fBposix_memalign()\fP). .sp This check implements \fI\%R.10\fP from the C++ Core Guidelines. .sp There is no attempt made to provide fix\-it hints, since manual resource management isn\(aqt easily transformed automatically into RAII. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Warns each of the following lines. // Containers like std::vector or std::string should be used. char* some_string = (char*) malloc(sizeof(char) * 20); char* some_string = (char*) realloc(sizeof(char) * 30); free(some_string); int* int_array = (int*) calloc(30, sizeof(int)); // Rather use a smartpointer or stack variable. struct some_struct* s = (struct some_struct*) malloc(sizeof(struct some_struct)); .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B Allocations Semicolon\-separated list of fully qualified names of memory allocation functions. Defaults to \fB::malloc;::calloc\fP\&. .UNINDENT .INDENT 0.0 .TP .B Deallocations Semicolon\-separated list of fully qualified names of memory allocation functions. Defaults to \fB::free\fP\&. .UNINDENT .INDENT 0.0 .TP .B Reallocations Semicolon\-separated list of fully qualified names of memory allocation functions. Defaults to \fB::realloc\fP\&. .UNINDENT .SS cppcoreguidelines\-noexcept\-destructor .sp This check implements \fI\%C.37\fP from the C++ Core Guidelines. .sp The cppcoreguidelines\-noexcept\-destructor check is an alias, please see \fI\%performance\-noexcept\-destructor\fP for more information. .SS cppcoreguidelines\-noexcept\-move\-operations .sp This check implements \fI\%C.66\fP from the C++ Core Guidelines. .sp The cppcoreguidelines\-noexcept\-move\-operations check is an alias, please see \fI\%performance\-noexcept\-move\-constructor\fP for more information. .SS cppcoreguidelines\-noexcept\-swap .sp This check implements \fI\%C.83\fP , \fI\%C.84\fP and \fI\%C.85\fP from the C++ Core Guidelines. .sp The cppcoreguidelines\-noexcept\-swap check is an alias, please see \fI\%performance\-noexcept\-swap\fP for more information. .SS cppcoreguidelines\-non\-private\-member\-variables\-in\-classes .sp The cppcoreguidelines\-non\-private\-member\-variables\-in\-classes check is an alias, please see \fI\%misc\-non\-private\-member\-variables\-in\-classes\fP for more information. .SS cppcoreguidelines\-owning\-memory .sp This check implements the type\-based semantics of \fBgsl::owner\fP, which allows static analysis on code, that uses raw pointers to handle resources like dynamic memory, but won\(aqt introduce RAII concepts. .sp This check implements \fI\%I.11\fP, \fI\%C.33\fP, \fI\%R.3\fP and \fI\%GSL.Views\fP from the C++ Core Guidelines. The definition of a \fBgsl::owner\fP is straight forward .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C namespace gsl { template owner = T; } .ft P .fi .UNINDENT .UNINDENT .sp It is therefore simple to introduce the owner even without using an implementation of the \fI\%Guideline Support Library\fP\&. .sp All checks are purely type based and not (yet) flow sensitive. .sp The following examples will demonstrate the correct and incorrect initializations of owners, assignment is handled the same way. Note that both \fBnew\fP and \fBmalloc()\fP\-like resource functions are considered to produce resources. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Creating an owner with factory functions is checked. gsl::owner function_that_returns_owner() { return gsl::owner(new int(42)); } // Dynamic memory must be assigned to an owner int* Something = new int(42); // BAD, will be caught gsl::owner Owner = new int(42); // Good gsl::owner Owner = new int[42]; // Good as well // Returned owner must be assigned to an owner int* Something = function_that_returns_owner(); // Bad, factory function gsl::owner Owner = function_that_returns_owner(); // Good, result lands in owner // Something not a resource or owner should not be assigned to owners int Stack = 42; gsl::owner Owned = &Stack; // Bad, not a resource assigned .ft P .fi .UNINDENT .UNINDENT .sp In the case of dynamic memory as resource, only \fBgsl::owner\fP variables are allowed to be deleted. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Example Bad, non\-owner as resource handle, will be caught. int* NonOwner = new int(42); // First warning here, since new must land in an owner delete NonOwner; // Second warning here, since only owners are allowed to be deleted // Example Good, Ownership correctly stated gsl::owner Owner = new int(42); // Good delete Owner; // Good as well, statically enforced, that only owners get deleted .ft P .fi .UNINDENT .UNINDENT .sp The check will furthermore ensure, that functions, that expect a \fBgsl::owner\fP as argument get called with either a \fBgsl::owner\fP or a newly created resource. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void expects_owner(gsl::owner o) { delete o; } // Bad Code int NonOwner = 42; expects_owner(&NonOwner); // Bad, will get caught // Good Code gsl::owner Owner = new int(42); expects_owner(Owner); // Good expects_owner(new int(42)); // Good as well, recognized created resource // Port legacy code for better resource\-safety gsl::owner File = fopen(\(dqmy_file.txt\(dq, \(dqrw+\(dq); FILE* BadFile = fopen(\(dqanother_file.txt\(dq, \(dqw\(dq); // Bad, warned // ... use the file fclose(File); // Ok, File is annotated as \(aqowner<>\(aq fclose(BadFile); // BadFile is not an \(aqowner<>\(aq, will be warned .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B LegacyResourceProducers Semicolon\-separated list of fully qualified names of legacy functions that create resources but cannot introduce \fBgsl::owner<>\fP\&. Defaults to \fB::malloc;::aligned_alloc;::realloc;::calloc;::fopen;::freopen;::tmpfile\fP\&. .UNINDENT .INDENT 0.0 .TP .B LegacyResourceConsumers Semicolon\-separated list of fully qualified names of legacy functions expecting resource owners as pointer arguments but cannot introduce \fBgsl::owner<>\fP\&. Defaults to \fB::free;::realloc;::freopen;::fclose\fP\&. .UNINDENT .SS Limitations .sp Using \fBgsl::owner\fP in a typedef or alias is not handled correctly. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C using heap_int = gsl::owner; heap_int allocated = new int(42); // False positive! .ft P .fi .UNINDENT .UNINDENT .sp The \fBgsl::owner\fP is declared as a templated type alias. In template functions and classes, like in the example below, the information of the type aliases gets lost. Therefore using \fBgsl::owner\fP in a heavy templated code base might lead to false positives. .sp Known code constructs that do not get diagnosed correctly are: .INDENT 0.0 .IP \(bu 2 \fBstd::exchange\fP .IP \(bu 2 \fBstd::vector>\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // This template function works as expected. Type information doesn\(aqt get lost. template void delete_owner(gsl::owner owned_object) { delete owned_object; // Everything alright } gsl::owner function_that_returns_owner() { return gsl::owner(new int(42)); } // Type deduction does not work for auto variables. // This is caught by the check and will be noted accordingly. auto OwnedObject = function_that_returns_owner(); // Type of OwnedObject will be int* // Problematic function template that looses the typeinformation on owner template void bad_template_function(T some_object) { // This line will trigger the warning, that a non\-owner is assigned to an owner gsl::owner new_owner = some_object; } // Calling the function with an owner still yields a false positive. bad_template_function(gsl::owner(new int(42))); // The same issue occurs with templated classes like the following. template class OwnedValue { public: const T getValue() const { return _val; } private: T _val; }; // Code, that yields a false positive. OwnedValue> Owner(new int(42)); // Type deduction yield T \-> int * // False positive, getValue returns int* and not gsl::owner gsl::owner OwnedInt = Owner.getValue(); .ft P .fi .UNINDENT .UNINDENT .sp Another limitation of the current implementation is only the type based checking. Suppose you have code like the following: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Two owners with assigned resources gsl::owner Owner1 = new int(42); gsl::owner Owner2 = new int(42); Owner2 = Owner1; // Conceptual Leak of initial resource of Owner2! Owner1 = nullptr; .ft P .fi .UNINDENT .UNINDENT .sp The semantic of a \fBgsl::owner\fP is mostly like a \fBstd::unique_ptr\fP, therefore assignment of two \fBgsl::owner\fP is considered a move, which requires that the resource \fBOwner2\fP must have been released before the assignment. This kind of condition could be caught in later improvements of this check with flowsensitive analysis. Currently, the \fIClang Static Analyzer\fP catches this bug for dynamic memory, but not for general types of resources. .SS cppcoreguidelines\-prefer\-member\-initializer .sp Finds member initializations in the constructor body which can be converted into member initializers of the constructor instead. This not only improves the readability of the code but also positively affects its performance. Class\-member assignments inside a control statement or following the first control statement are ignored. .sp This check implements \fI\%C.49\fP from the C++ Core Guidelines. .sp If the language version is \fIC++ 11\fP or above, the constructor is the default constructor of the class, the field is not a bitfield (only in case of earlier language version than \fIC++ 20\fP), furthermore the assigned value is a literal, negated literal or \fBenum\fP constant then the preferred place of the initialization is at the class member declaration. .sp This latter rule is \fI\%C.48\fP from the C++ Core Guidelines. .sp Please note, that this check does not enforce this latter rule for initializations already implemented as member initializers. For that purpose see check \fI\%modernize\-use\-default\-member\-init\fP\&. .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 Enforcement of rule C.48 in this check is deprecated, to be removed in \fBclang\-tidy\fP version 19 (only C.49 will be enforced by this check then). Please use \fI\%cppcoreguidelines\-use\-default\-member\-init\fP to enforce rule C.48. .UNINDENT .UNINDENT .SS Example 1 .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class C { int n; int m; public: C() { n = 1; // Literal in default constructor if (dice()) return; m = 1; } }; .ft P .fi .UNINDENT .UNINDENT .sp Here \fBn\fP can be initialized using a default member initializer, unlike \fBm\fP, as \fBm\fP\(aqs initialization follows a control statement (\fBif\fP): .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class C { int n{1}; int m; public: C() { if (dice()) return; m = 1; } .ft P .fi .UNINDENT .UNINDENT .SS Example 2 .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class C { int n; int m; public: C(int nn, int mm) { n = nn; // Neither default constructor nor literal if (dice()) return; m = mm; } }; .ft P .fi .UNINDENT .UNINDENT .sp Here \fBn\fP can be initialized in the constructor initialization list, unlike \fBm\fP, as \fBm\fP\(aqs initialization follows a control statement (\fBif\fP): .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C C(int nn, int mm) : n(nn) { if (dice()) return; m = mm; } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B UseAssignment Note: this option is deprecated, to be removed in \fBclang\-tidy\fP version 19. Please use the \fIUseAssignment\fP option from \fI\%cppcoreguidelines\-use\-default\-member\-init\fP instead. .sp If this option is set to \fItrue\fP (by default \fIUseAssignment\fP from \fI\%modernize\-use\-default\-member\-init\fP will be used), the check will initialize members with an assignment. In this case the fix of the first example looks like this: .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class C { int n = 1; int m; public: C() { if (dice()) return; m = 1; } }; .ft P .fi .UNINDENT .UNINDENT .SS cppcoreguidelines\-pro\-bounds\-array\-to\-pointer\-decay .sp This check flags all array to pointer decays. .sp Pointers should not be used as arrays. \fBspan\fP is a bounds\-checked, safe alternative to using pointers to access arrays. .sp This rule is part of the \fI\%Bounds safety (Bounds 3)\fP profile from the C++ Core Guidelines. .SS cppcoreguidelines\-pro\-bounds\-constant\-array\-index .sp This check flags all array subscript expressions on static arrays and \fBstd::arrays\fP that either do not have a constant integer expression index or are out of bounds (for \fBstd::array\fP). For out\-of\-bounds checking of static arrays, see the \fI\-Warray\-bounds\fP Clang diagnostic. .sp This rule is part of the \fI\%Bounds safety (Bounds 2)\fP profile from the C++ Core Guidelines. .sp Optionally, this check can generate fixes using \fBgsl::at\fP for indexing. .SS Options .INDENT 0.0 .TP .B GslHeader The check can generate fixes after this option has been set to the name of the include file that contains \fBgsl::at()\fP, e.g. \fI\(dqgsl/gsl.h\(dq\fP\&. .UNINDENT .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .SS cppcoreguidelines\-pro\-bounds\-pointer\-arithmetic .sp This check flags all usage of pointer arithmetic, because it could lead to an invalid pointer. Subtraction of two pointers is not flagged by this check. .sp Pointers should only refer to single objects, and pointer arithmetic is fragile and easy to get wrong. \fBspan\fP is a bounds\-checked, safe type for accessing arrays of data. .sp This rule is part of the \fI\%Bounds safety (Bounds 1)\fP profile from the C++ Core Guidelines. .SS cppcoreguidelines\-pro\-type\-const\-cast .sp This check flags all uses of \fBconst_cast\fP in C++ code. .sp Modifying a variable that was declared const is undefined behavior, even with \fBconst_cast\fP\&. .sp This rule is part of the \fI\%Type safety (Type 3)\fP profile from the C++ Core Guidelines. .SS cppcoreguidelines\-pro\-type\-cstyle\-cast .sp This check flags all use of C\-style casts that perform a \fBstatic_cast\fP downcast, \fBconst_cast\fP, or \fBreinterpret_cast\fP\&. .sp Use of these casts can violate type safety and cause the program to access a variable that is actually of type X to be accessed as if it were of an unrelated type Z. Note that a C\-style \fB(T)expression\fP cast means to perform the first of the following that is possible: a \fBconst_cast\fP, a \fBstatic_cast\fP, a \fBstatic_cast\fP followed by a \fBconst_cast\fP, a \fBreinterpret_cast\fP, or a \fBreinterpret_cast\fP followed by a \fBconst_cast\fP\&. This rule bans \fB(T)expression\fP only when used to perform an unsafe cast. .sp This rule is part of the \fI\%Type safety (Type.4)\fP profile from the C++ Core Guidelines. .SS cppcoreguidelines\-pro\-type\-member\-init .sp The check flags user\-defined constructor definitions that do not initialize all fields that would be left in an undefined state by default construction, e.g. builtins, pointers and record types without user\-provided default constructors containing at least one such type. If these fields aren\(aqt initialized, the constructor will leave some of the memory in an undefined state. .sp For C++11 it suggests fixes to add in\-class field initializers. For older versions it inserts the field initializers into the constructor initializer list. It will also initialize any direct base classes that need to be zeroed in the constructor initializer list. .sp The check takes assignment of fields in the constructor body into account but generates false positives for fields initialized in methods invoked in the constructor body. .sp The check also flags variables with automatic storage duration that have record types without a user\-provided constructor and are not initialized. The suggested fix is to zero initialize the variable via \fB{}\fP for C++11 and beyond or \fB= {}\fP for older language versions. .SS Options .INDENT 0.0 .TP .B IgnoreArrays If set to \fItrue\fP, the check will not warn about array members that are not zero\-initialized during construction. For performance critical code, it may be important to not initialize fixed\-size array members. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B UseAssignment If set to \fItrue\fP, the check will provide fix\-its with literal initializers ( \fBint i = 0;\fP ) instead of curly braces ( \fBint i{};\fP ). .UNINDENT .sp This rule is part of the \fI\%Type safety (Type.6)\fP profile from the C++ Core Guidelines. .SS cppcoreguidelines\-pro\-type\-reinterpret\-cast .sp This check flags all uses of \fBreinterpret_cast\fP in C++ code. .sp Use of these casts can violate type safety and cause the program to access a variable that is actually of type \fBX\fP to be accessed as if it were of an unrelated type \fBZ\fP\&. .sp This rule is part of the \fI\%Type safety (Type.1.1)\fP profile from the C++ Core Guidelines. .SS cppcoreguidelines\-pro\-type\-static\-cast\-downcast .sp This check flags all usages of \fBstatic_cast\fP, where a base class is casted to a derived class. In those cases, a fix\-it is provided to convert the cast to a \fBdynamic_cast\fP\&. .sp Use of these casts can violate type safety and cause the program to access a variable that is actually of type \fBX\fP to be accessed as if it were of an unrelated type \fBZ\fP\&. .sp This rule is part of the \fI\%Type safety (Type.2)\fP profile from the C++ Core Guidelines. .SS cppcoreguidelines\-pro\-type\-union\-access .sp This check flags all access to members of unions. Passing unions as a whole is not flagged. .sp Reading from a union member assumes that member was the last one written, and writing to a union member assumes another member with a nontrivial destructor had its destructor called. This is fragile because it cannot generally be enforced to be safe in the language and so relies on programmer discipline to get it right. .sp This rule is part of the \fI\%Type safety (Type.7)\fP profile from the C++ Core Guidelines. .SS cppcoreguidelines\-pro\-type\-vararg .sp This check flags all calls to c\-style vararg functions and all use of \fBva_arg\fP\&. .sp To allow for SFINAE use of vararg functions, a call is not flagged if a literal 0 is passed as the only vararg argument. .sp Passing to varargs assumes the correct type will be read. This is fragile because it cannot generally be enforced to be safe in the language and so relies on programmer discipline to get it right. .sp This rule is part of the \fI\%Type safety (Type.8)\fP profile from the C++ Core Guidelines. .SS cppcoreguidelines\-rvalue\-reference\-param\-not\-moved .sp Warns when an rvalue reference function parameter is never moved within the function body. .sp Rvalue reference parameters indicate a parameter that should be moved with \fBstd::move\fP from within the function body. Any such parameter that is never moved is confusing and potentially indicative of a buggy program. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void logic(std::string&& Input) { std::string Copy(Input); // Oops \- forgot to std::move } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B AllowPartialMove .INDENT 7.0 .INDENT 3.5 If set to \fItrue\fP, the check accepts \fBstd::move\fP calls containing any subexpression containing the parameter. CppCoreGuideline F.18 officially mandates that the parameter itself must be moved. Default is \fIfalse\fP\&. .UNINDENT .UNINDENT .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C // \(aqp\(aq is flagged by this check if and only if AllowPartialMove is false void move_members_of(pair&& p) { pair other; other.first = std::move(p.first); other.second = std::move(p.second); } // \(aqp\(aq is never flagged by this check void move_whole_pair(pair&& p) { pair other = std::move(p); } .ft P .fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B IgnoreUnnamedParams If set to \fItrue\fP, the check ignores unnamed rvalue reference parameters. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreNonDeducedTemplateTypes .INDENT 7.0 .INDENT 3.5 If set to \fItrue\fP, the check ignores non\-deduced template type rvalue reference parameters. Default is \fIfalse\fP\&. .UNINDENT .UNINDENT .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C template struct SomeClass { // Below, \(aqT\(aq is not deduced and \(aqT&&\(aq is an rvalue reference type. // This will be flagged if and only if IgnoreNonDeducedTemplateTypes is // false. One suggested fix would be to specialize the class for \(aqT\(aq and // \(aqT&\(aq separately (e.g., see std::future), or allow only one of \(aqT\(aq or // \(aqT&\(aq instantiations of SomeClass (e.g., see std::optional). SomeClass(T&& t) { } }; // Never flagged, since \(aqT\(aq is a forwarding reference in a deduced context template void forwarding_ref(T&& t) { T other = std::forward(t); } .ft P .fi .UNINDENT .UNINDENT .UNINDENT .sp This check implements \fI\%F.18\fP from the C++ Core Guidelines. .SS cppcoreguidelines\-slicing .sp Flags slicing of member variables or vtable. Slicing happens when copying a derived object into a base object: the members of the derived object (both member variables and virtual member functions) will be discarded. This can be misleading especially for member function slicing, for example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct B { int a; virtual int f(); }; struct D : B { int b; int f() override; }; void use(B b) { // Missing reference, intended? b.f(); // Calls B::f. } D d; use(d); // Slice. .ft P .fi .UNINDENT .UNINDENT .sp This check implements \fI\%ES.63\fP and \fI\%C.145\fP from the C++ Core Guidelines. .SS cppcoreguidelines\-special\-member\-functions .sp The check finds classes where some but not all of the special member functions are defined. .sp By default the compiler defines a copy constructor, copy assignment operator, move constructor, move assignment operator and destructor. The default can be suppressed by explicit user\-definitions. The relationship between which functions will be suppressed by definitions of other functions is complicated and it is advised that all five are defaulted or explicitly defined. .sp Note that defining a function with \fB= delete\fP is considered to be a definition. .sp This check implements \fI\%C.21\fP from the C++ Core Guidelines. .SS Options .INDENT 0.0 .TP .B AllowSoleDefaultDtor When set to \fItrue\fP (default is \fIfalse\fP), this check will only trigger on destructors if they are defined and not defaulted. .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C struct A { // This is fine. virtual ~A() = default; }; struct B { // This is not fine. ~B() {} }; struct C { // This is not checked, because the destructor might be defaulted in // another translation unit. ~C(); }; .ft P .fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B AllowMissingMoveFunctions When set to \fItrue\fP (default is \fIfalse\fP), this check doesn\(aqt flag classes which define no move operations at all. It still flags classes which define only one of either move constructor or move assignment operator. With this option enabled, the following class won\(aqt be flagged: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C struct A { A(const A&); A& operator=(const A&); ~A(); }; .ft P .fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B AllowMissingMoveFunctionsWhenCopyIsDeleted When set to \fItrue\fP (default is \fIfalse\fP), this check doesn\(aqt flag classes which define deleted copy operations but don\(aqt define move operations. This flag is related to Google C++ Style Guide \fI\%https://google.github.io/styleguide/cppguide.html#Copyable_Movable_Types\fP\&. With this option enabled, the following class won\(aqt be flagged: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C struct A { A(const A&) = delete; A& operator=(const A&) = delete; ~A(); }; .ft P .fi .UNINDENT .UNINDENT .UNINDENT .SS cppcoreguidelines\-use\-default\-member\-init .sp This check implements \fI\%C.48\fP from the C++ Core Guidelines. .sp The cppcoreguidelines\-use\-default\-member\-init check is an alias, please see \fI\%modernize\-use\-default\-member\-init\fP for more information. .SS cppcoreguidelines\-virtual\-class\-destructor .sp Finds virtual classes whose destructor is neither public and virtual nor protected and non\-virtual. A virtual class\(aqs destructor should be specified in one of these ways to prevent undefined behavior. .sp This check implements \fI\%C.35\fP from the C++ Core Guidelines. .sp Note that this check will diagnose a class with a virtual method regardless of whether the class is used as a base class or not. .sp Fixes are available for user\-declared and implicit destructors that are either public and non\-virtual or protected and virtual. No fixes are offered for private destructors. There, the decision whether to make them private and virtual or protected and non\-virtual depends on the use case and is thus left to the user. .SS Example .sp For example, the following classes/structs get flagged by the check since they violate guideline \fBC.35\fP: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct Foo { // NOK, protected destructor should not be virtual virtual void f(); protected: virtual ~Foo(){} }; class Bar { // NOK, public destructor should be virtual virtual void f(); public: ~Bar(){} }; .ft P .fi .UNINDENT .UNINDENT .sp This would be rewritten to look like this: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct Foo { // OK, destructor is not virtual anymore virtual void f(); protected: ~Foo(){} }; class Bar { // OK, destructor is now virtual virtual void f(); public: virtual ~Bar(){} }; .ft P .fi .UNINDENT .UNINDENT .SS darwin\-avoid\-spinlock .sp Finds usages of \fBOSSpinlock\fP, which is deprecated due to potential livelock problems. .sp This check will detect following function invocations: .INDENT 0.0 .IP \(bu 2 \fBOSSpinlockLock\fP .IP \(bu 2 \fBOSSpinlockTry\fP .IP \(bu 2 \fBOSSpinlockUnlock\fP .UNINDENT .sp The corresponding information about the problem of \fBOSSpinlock\fP: \fI\%https://blog.postmates.com/why\-spinlocks\-are\-bad\-on\-ios\-b69fc5221058\fP .SS darwin\-dispatch\-once\-nonstatic .sp Finds declarations of \fBdispatch_once_t\fP variables without static or global storage. The behavior of using \fBdispatch_once_t\fP predicates with automatic or dynamic storage is undefined by libdispatch, and should be avoided. .sp It is a common pattern to have functions initialize internal static or global data once when the function runs, but programmers have been known to miss the static on the \fBdispatch_once_t\fP predicate, leading to an uninitialized flag value at the mercy of the stack. .sp Programmers have also been known to make \fBdispatch_once_t\fP variables be members of structs or classes, with the intent to lazily perform some expensive struct or class member initialization only once; however, this violates the libdispatch requirements. .sp See the discussion section of \fI\%Apple\(aqs dispatch_once documentation\fP for more information. .SS fuchsia\-default\-arguments\-calls .sp Warns if a function or method is called with default arguments. .sp For example, given the declaration: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int foo(int value = 5) { return value; } .ft P .fi .UNINDENT .UNINDENT .sp A function call expression that uses a default argument will be diagnosed. Calling it without defaults will not cause a warning: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C foo(); // warning foo(0); // no warning .ft P .fi .UNINDENT .UNINDENT .sp See the features disallowed in Fuchsia at \fI\%https://fuchsia.dev/fuchsia\-src/development/languages/c\-cpp/cxx?hl=en\fP .SS fuchsia\-default\-arguments\-declarations .sp Warns if a function or method is declared with default parameters. .sp For example, the declaration: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int foo(int value = 5) { return value; } .ft P .fi .UNINDENT .UNINDENT .sp will cause a warning. .sp See the features disallowed in Fuchsia at \fI\%https://fuchsia.dev/fuchsia\-src/development/languages/c\-cpp/cxx?hl=en\fP .SS fuchsia\-header\-anon\-namespaces .sp The fuchsia\-header\-anon\-namespaces check is an alias, please see \fI\%google\-build\-namespace\fP for more information. .SS fuchsia\-multiple\-inheritance .sp Warns if a class inherits from multiple classes that are not pure virtual. .sp For example, declaring a class that inherits from multiple concrete classes is disallowed: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Base_A { public: virtual int foo() { return 0; } }; class Base_B { public: virtual int bar() { return 0; } }; // Warning class Bad_Child1 : public Base_A, Base_B {}; .ft P .fi .UNINDENT .UNINDENT .sp A class that inherits from a pure virtual is allowed: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Interface_A { public: virtual int foo() = 0; }; class Interface_B { public: virtual int bar() = 0; }; // No warning class Good_Child1 : public Interface_A, Interface_B { virtual int foo() override { return 0; } virtual int bar() override { return 0; } }; .ft P .fi .UNINDENT .UNINDENT .sp See the features disallowed in Fuchsia at \fI\%https://fuchsia.dev/fuchsia\-src/development/languages/c\-cpp/cxx?hl=en\fP .SS fuchsia\-overloaded\-operator .sp Warns if an operator is overloaded, except for the assignment (copy and move) operators. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int operator+(int); // Warning B &operator=(const B &Other); // No warning B &operator=(B &&Other) // No warning .ft P .fi .UNINDENT .UNINDENT .sp See the features disallowed in Fuchsia at \fI\%https://fuchsia.dev/fuchsia\-src/development/languages/c\-cpp/cxx?hl=en\fP .SS fuchsia\-statically\-constructed\-objects .sp Warns if global, non\-trivial objects with static storage are constructed, unless the object is statically initialized with a \fBconstexpr\fP constructor or has no explicit constructor. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class A {}; class B { public: B(int Val) : Val(Val) {} private: int Val; }; class C { public: C(int Val) : Val(Val) {} constexpr C() : Val(0) {} private: int Val; }; static A a; // No warning, as there is no explicit constructor static C c(0); // No warning, as constructor is constexpr static B b(0); // Warning, as constructor is not constexpr static C c2(0, 1); // Warning, as constructor is not constexpr static int i; // No warning, as it is trivial extern int get_i(); static C(get_i()) // Warning, as the constructor is dynamically initialized .ft P .fi .UNINDENT .UNINDENT .sp See the features disallowed in Fuchsia at \fI\%https://fuchsia.dev/fuchsia\-src/development/languages/c\-cpp/cxx?hl=en\fP .SS fuchsia\-trailing\-return .sp Functions that have trailing returns are disallowed, except for those using \fBdecltype\fP specifiers and lambda with otherwise unutterable return types. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // No warning int add_one(const int arg) { return arg; } // Warning auto get_add_one() \-> int (*)(const int) { return add_one; } .ft P .fi .UNINDENT .UNINDENT .sp Exceptions are made for lambdas and \fBdecltype\fP specifiers: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // No warning auto lambda = [](double x, double y) \-> double {return x + y;}; // No warning template auto fn(const T1 &lhs, const T2 &rhs) \-> decltype(lhs + rhs) { return lhs + rhs; } .ft P .fi .UNINDENT .UNINDENT .sp See the features disallowed in Fuchsia at \fI\%https://fuchsia.dev/fuchsia\-src/development/languages/c\-cpp/cxx?hl=en\fP .SS fuchsia\-virtual\-inheritance .sp Warns if classes are defined with virtual inheritance. .sp For example, classes should not be defined with virtual inheritance: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class B : public virtual A {}; // warning .ft P .fi .UNINDENT .UNINDENT .sp See the features disallowed in Fuchsia at \fI\%https://fuchsia.dev/fuchsia\-src/development/languages/c\-cpp/cxx?hl=en\fP .SS google\-build\-explicit\-make\-pair .sp Check that \fBmake_pair\fP\(aqs template arguments are deduced. .sp G++ 4.6 in C++11 mode fails badly if \fBmake_pair\fP\(aqs template arguments are specified explicitly, and such use isn\(aqt intended in any case. .sp Corresponding cpplint.py check name: \fIbuild/explicit_make_pair\fP\&. .SS google\-build\-namespaces .sp \fIcert\-dcl59\-cpp\fP redirects here as an alias for this check. \fIfuchsia\-header\-anon\-namespaces\fP redirects here as an alias for this check. .sp Finds anonymous namespaces in headers. .sp \fI\%https://google.github.io/styleguide/cppguide.html#Namespaces\fP .sp Corresponding cpplint.py check name: \fIbuild/namespaces\fP\&. .SS Options .INDENT 0.0 .TP .B HeaderFileExtensions Note: this option is deprecated, it will be removed in \fBclang\-tidy\fP version 19. Please use the global configuration option \fIHeaderFileExtensions\fP\&. .sp A comma\-separated list of filename extensions of header files (the filename extensions should not include \(dq.\(dq prefix). Default is \(dqh,hh,hpp,hxx\(dq. For header files without an extension, use an empty string (if there are no other desired extensions) or leave an empty element in the list. E.g., \(dqh,hh,hpp,hxx,\(dq (note the trailing comma). .UNINDENT .SS google\-build\-using\-namespace .sp Finds \fBusing namespace\fP directives. .sp The check implements the following rule of the \fI\%Google C++ Style Guide\fP: .INDENT 0.0 .INDENT 3.5 You may not use a using\-directive to make all names from a namespace available. .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Forbidden \-\- This pollutes the namespace. using namespace foo; .ft P .fi .UNINDENT .UNINDENT .sp Corresponding cpplint.py check name: \fIbuild/namespaces\fP\&. .SS google\-default\-arguments .sp Checks that default arguments are not given for virtual methods. .sp See \fI\%https://google.github.io/styleguide/cppguide.html#Default_Arguments\fP .SS google\-explicit\-constructor .sp Checks that constructors callable with a single argument and conversion operators are marked explicit to avoid the risk of unintentional implicit conversions. .sp Consider this example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct S { int x; operator bool() const { return true; } }; bool f() { S a{1}; S b{2}; return a == b; } .ft P .fi .UNINDENT .UNINDENT .sp The function will return \fBtrue\fP, since the objects are implicitly converted to \fBbool\fP before comparison, which is unlikely to be the intent. .sp The check will suggest inserting \fBexplicit\fP before the constructor or conversion operator declaration. However, copy and move constructors should not be explicit, as well as constructors taking a single \fBinitializer_list\fP argument. .sp This code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct S { S(int a); explicit S(const S&); operator bool() const; ... .ft P .fi .UNINDENT .UNINDENT .sp will become .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct S { explicit S(int a); S(const S&); explicit operator bool() const; ... .ft P .fi .UNINDENT .UNINDENT .sp See \fI\%https://google.github.io/styleguide/cppguide.html#Explicit_Constructors\fP .SS google\-global\-names\-in\-headers .sp Flag global namespace pollution in header files. Right now it only triggers on \fBusing\fP declarations and directives. .sp The relevant style guide section is \fI\%https://google.github.io/styleguide/cppguide.html#Namespaces\fP\&. .SS Options .INDENT 0.0 .TP .B HeaderFileExtensions Note: this option is deprecated, it will be removed in \fBclang\-tidy\fP version 19. Please use the global configuration option \fIHeaderFileExtensions\fP\&. .sp A comma\-separated list of filename extensions of header files (the filename extensions should not contain \(dq.\(dq prefix). Default is \(dqh\(dq. For header files without an extension, use an empty string (if there are no other desired extensions) or leave an empty element in the list. E.g., \(dqh,hh,hpp,hxx,\(dq (note the trailing comma). .UNINDENT .SS google\-objc\-avoid\-nsobject\-new .sp Finds calls to \fB+new\fP or overrides of it, which are prohibited by the Google Objective\-C style guide. .sp The Google Objective\-C style guide forbids calling \fB+new\fP or overriding it in class implementations, preferring \fB+alloc\fP and \fB\-init\fP methods to instantiate objects. .sp An example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C NSDate *now = [NSDate new]; Foo *bar = [Foo new]; .ft P .fi .UNINDENT .UNINDENT .sp Instead, code should use \fB+alloc\fP/\fB\-init\fP or class factory methods. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C NSDate *now = [NSDate date]; Foo *bar = [[Foo alloc] init]; .ft P .fi .UNINDENT .UNINDENT .sp This check corresponds to the Google Objective\-C Style Guide rule \fI\%Do Not Use +new\fP\&. .SS google\-objc\-avoid\-throwing\-exception .sp Finds uses of throwing exceptions usages in Objective\-C files. .sp For the same reason as the Google C++ style guide, we prefer not throwing exceptions from Objective\-C code. .sp The corresponding C++ style guide rule: \fI\%https://google.github.io/styleguide/cppguide.html#Exceptions\fP .sp Instead, prefer passing in \fBNSError **\fP and return \fBBOOL\fP to indicate success or failure. .sp A counterexample: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \- (void)readFile { if ([self isError]) { @throw [NSException exceptionWithName:...]; } } .ft P .fi .UNINDENT .UNINDENT .sp Instead, returning an error via \fBNSError **\fP is preferred: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \- (BOOL)readFileWithError:(NSError **)error { if ([self isError]) { *error = [NSError errorWithDomain:...]; return NO; } return YES; } .ft P .fi .UNINDENT .UNINDENT .sp The corresponding style guide rule: \fI\%https://google.github.io/styleguide/objcguide.html#avoid\-throwing\-exceptions\fP .SS google\-objc\-function\-naming .sp Finds function declarations in Objective\-C files that do not follow the pattern described in the Google Objective\-C Style Guide. .sp The corresponding style guide rule can be found here: \fI\%https://google.github.io/styleguide/objcguide.html#function\-names\fP .sp All function names should be in Pascal case. Functions whose storage class is not static should have an appropriate prefix. .sp The following code sample does not follow this pattern: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static bool is_positive(int i) { return i > 0; } bool IsNegative(int i) { return i < 0; } .ft P .fi .UNINDENT .UNINDENT .sp The sample above might be corrected to the following code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static bool IsPositive(int i) { return i > 0; } bool *ABCIsNegative(int i) { return i < 0; } .ft P .fi .UNINDENT .UNINDENT .SS google\-objc\-global\-variable\-declaration .sp Finds global variable declarations in Objective\-C files that do not follow the pattern of variable names in Google\(aqs Objective\-C Style Guide. .sp The corresponding style guide rule: \fI\%https://google.github.io/styleguide/objcguide.html#variable\-names\fP .sp All the global variables should follow the pattern of \fBg[A\-Z].*\fP (variables) or \fBk[A\-Z].*\fP (constants). The check will suggest a variable name that follows the pattern if it can be inferred from the original name. .sp For code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static NSString* myString = @\(dqhello\(dq; .ft P .fi .UNINDENT .UNINDENT .sp The fix will be: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static NSString* gMyString = @\(dqhello\(dq; .ft P .fi .UNINDENT .UNINDENT .sp Another example of constant: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static NSString* const myConstString = @\(dqhello\(dq; .ft P .fi .UNINDENT .UNINDENT .sp The fix will be: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static NSString* const kMyConstString = @\(dqhello\(dq; .ft P .fi .UNINDENT .UNINDENT .sp However for code that prefixed with non\-alphabetical characters like: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static NSString* __anotherString = @\(dqworld\(dq; .ft P .fi .UNINDENT .UNINDENT .sp The check will give a warning message but will not be able to suggest a fix. The user needs to fix it on their own. .SS google\-readability\-avoid\-underscore\-in\-googletest\-name .sp Checks whether there are underscores in googletest test suite names and test names in test macros: .INDENT 0.0 .IP \(bu 2 \fBTEST\fP .IP \(bu 2 \fBTEST_F\fP .IP \(bu 2 \fBTEST_P\fP .IP \(bu 2 \fBTYPED_TEST\fP .IP \(bu 2 \fBTYPED_TEST_P\fP .UNINDENT .sp The \fBFRIEND_TEST\fP macro is not included. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C TEST(TestSuiteName, Illegal_TestName) {} TEST(Illegal_TestSuiteName, TestName) {} .ft P .fi .UNINDENT .UNINDENT .sp would trigger the check. \fI\%Underscores are not allowed\fP in test suite name nor test names. .sp The \fBDISABLED_\fP prefix, which may be used to \fI\%disable test suites and individual tests\fP, is removed from the test suite name and test name before checking for underscores. .sp This check does not propose any fixes. .SS google\-readability\-braces\-around\-statements .sp The google\-readability\-braces\-around\-statements check is an alias, please see \fI\%readability\-braces\-around\-statements\fP for more information. .SS google\-readability\-casting .sp Finds usages of C\-style casts. .sp \fI\%https://google.github.io/styleguide/cppguide.html#Casting\fP .sp Corresponding cpplint.py check name: \fIreadability/casting\fP\&. .sp This check is similar to \fB\-Wold\-style\-cast\fP, but it suggests automated fixes in some cases. The reported locations should not be different from the ones generated by \fB\-Wold\-style\-cast\fP\&. .SS google\-readability\-function\-size .sp The google\-readability\-function\-size check is an alias, please see \fI\%readability\-function\-size\fP for more information. .SS google\-readability\-namespace\-comments .sp The google\-readability\-namespace\-comments check is an alias, please see \fI\%llvm\-namespace\-comment\fP for more information. .SS google\-readability\-todo .sp Finds TODO comments without a username or bug number. .sp The relevant style guide section is \fI\%https://google.github.io/styleguide/cppguide.html#TODO_Comments\fP\&. .sp Corresponding cpplint.py check: \fIreadability/todo\fP .SS google\-runtime\-int .sp Finds uses of \fBshort\fP, \fBlong\fP and \fBlong long\fP and suggest replacing them with \fBu?intXX(_t)?\fP\&. .sp The corresponding style guide rule: \fI\%https://google.github.io/styleguide/cppguide.html#Integer_Types\fP\&. .sp Corresponding cpplint.py check: \fIruntime/int\fP\&. .SS Options .INDENT 0.0 .TP .B UnsignedTypePrefix A string specifying the unsigned type prefix. Default is \fIuint\fP\&. .UNINDENT .INDENT 0.0 .TP .B SignedTypePrefix A string specifying the signed type prefix. Default is \fIint\fP\&. .UNINDENT .INDENT 0.0 .TP .B TypeSuffix A string specifying the type suffix. Default is an empty string. .UNINDENT .SS google\-runtime\-operator .sp Finds overloads of unary \fBoperator &\fP\&. .sp \fI\%https://google.github.io/styleguide/cppguide.html#Operator_Overloading\fP .sp Corresponding cpplint.py check name: \fIruntime/operator\fP\&. .SS google\-upgrade\-googletest\-case .sp Finds uses of deprecated Google Test version 1.9 APIs with names containing \fBcase\fP and replaces them with equivalent APIs with \fBsuite\fP\&. .sp All names containing \fBcase\fP are being replaced to be consistent with the meanings of \(dqtest case\(dq and \(dqtest suite\(dq as used by the International Software Testing Qualifications Board and ISO 29119. .sp The new names are a part of Google Test version 1.9 (release pending). It is recommended that users update their dependency to version 1.9 and then use this check to remove deprecated names. .sp The affected APIs are: .INDENT 0.0 .IP \(bu 2 Member functions of \fBtesting::Test\fP, \fBtesting::TestInfo\fP, \fBtesting::TestEventListener\fP, \fBtesting::UnitTest\fP, and any type inheriting from these types .IP \(bu 2 The macros \fBTYPED_TEST_CASE\fP, \fBTYPED_TEST_CASE_P\fP, \fBREGISTER_TYPED_TEST_CASE_P\fP, and \fBINSTANTIATE_TYPED_TEST_CASE_P\fP .IP \(bu 2 The type alias \fBtesting::TestCase\fP .UNINDENT .sp Examples of fixes created by this check: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class FooTest : public testing::Test { public: static void SetUpTestCase(); static void TearDownTestCase(); }; TYPED_TEST_CASE(BarTest, BarTypes); .ft P .fi .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class FooTest : public testing::Test { public: static void SetUpTestSuite(); static void TearDownTestSuite(); }; TYPED_TEST_SUITE(BarTest, BarTypes); .ft P .fi .UNINDENT .UNINDENT .sp For better consistency of user code, the check renames both virtual and non\-virtual member functions with matching names in derived types. The check tries to provide only a warning when a fix cannot be made safely, as is the case with some template and macro uses. .SS hicpp\-avoid\-c\-arrays .sp The hicpp\-avoid\-c\-arrays check is an alias, please see \fI\%modernize\-avoid\-c\-arrays\fP for more information. .SS hicpp\-avoid\-goto .sp The \fIhicpp\-avoid\-goto\fP check is an alias to \fI\%cppcoreguidelines\-avoid\-goto\fP\&. Rule \fI\%6.3.1 High Integrity C++\fP requires that \fBgoto\fP only skips parts of a block and is not used for other reasons. .sp Both coding guidelines implement the same exception to the usage of \fBgoto\fP\&. .SS hicpp\-braces\-around\-statements .sp The \fIhicpp\-braces\-around\-statements\fP check is an alias, please see \fI\%readability\-braces\-around\-statements\fP for more information. It enforces the \fI\%rule 6.1.1\fP\&. .SS hicpp\-deprecated\-headers .sp The \fIhicpp\-deprecated\-headers\fP check is an alias, please see \fI\%modernize\-deprecated\-headers\fP for more information. It enforces the \fI\%rule 1.3.3\fP\&. .SS hicpp\-exception\-baseclass .sp Ensure that every value that in a \fBthrow\fP expression is an instance of \fBstd::exception\fP\&. .sp This enforces \fI\%rule 15.1\fP of the High Integrity C++ Coding Standard. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class custom_exception {}; void throwing() noexcept(false) { // Problematic throw expressions. throw int(42); throw custom_exception(); } class mathematical_error : public std::exception {}; void throwing2() noexcept(false) { // These kind of throws are ok. throw mathematical_error(); throw std::runtime_error(); throw std::exception(); } .ft P .fi .UNINDENT .UNINDENT .SS hicpp\-explicit\-conversions .sp This check is an alias for \fI\%google\-explicit\-constructor\fP\&. Used to enforce parts of \fI\%rule 5.4.1\fP\&. This check will enforce that constructors and conversion operators are marked \fIexplicit\fP\&. Other forms of casting checks are implemented in other places. The following checks can be used to check for more forms of casting: .INDENT 0.0 .IP \(bu 2 \fI\%cppcoreguidelines\-pro\-type\-static\-cast\-downcast\fP .IP \(bu 2 \fI\%cppcoreguidelines\-pro\-type\-reinterpret\-cast\fP .IP \(bu 2 \fI\%cppcoreguidelines\-pro\-type\-const\-cast\fP .IP \(bu 2 \fI\%cppcoreguidelines\-pro\-type\-cstyle\-cast\fP .UNINDENT .SS hicpp\-function\-size .sp This check is an alias for \fI\%readability\-function\-size\fP\&. Useful to enforce multiple sections on function complexity. .INDENT 0.0 .IP \(bu 2 \fI\%rule 8.2.2\fP .IP \(bu 2 \fI\%rule 8.3.1\fP .IP \(bu 2 \fI\%rule 8.3.2\fP .UNINDENT .SS hicpp\-invalid\-access\-moved .sp This check is an alias for \fI\%bugprone\-use\-after\-move\fP\&. .sp Implements parts of the \fI\%rule 8.4.1\fP to check if moved\-from objects are accessed. .SS hicpp\-member\-init .sp This check is an alias for \fI\%cppcoreguidelines\-pro\-type\-member\-init\fP\&. Implements the check for \fI\%rule 12.4.2\fP to initialize class members in the right order. .SS hicpp\-move\-const\-arg .sp The \fIhicpp\-move\-const\-arg\fP check is an alias, please see \fI\%performance\-move\-const\-arg\fP for more information. It enforces the \fI\%rule 17.3.1\fP\&. .SS hicpp\-multiway\-paths\-covered .sp This check discovers situations where code paths are not fully\-covered. It furthermore suggests using \fBif\fP instead of \fBswitch\fP if the code will be more clear. The \fI\%rule 6.1.2\fP and \fI\%rule 6.1.4\fP of the High Integrity C++ Coding Standard are enforced. .sp \fBif\-else if\fP chains that miss a final \fBelse\fP branch might lead to unexpected program execution and be the result of a logical error. If the missing \fBelse\fP branch is intended you can leave it empty with a clarifying comment. This warning can be noisy on some code bases, so it is disabled by default. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f1() { int i = determineTheNumber(); if(i > 0) { // Some Calculation } else if (i < 0) { // Precondition violated or something else. } // ... } .ft P .fi .UNINDENT .UNINDENT .sp Similar arguments hold for \fBswitch\fP statements which do not cover all possible code paths. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // The missing default branch might be a logical error. It can be kept empty // if there is nothing to do, making it explicit. void f2(int i) { switch (i) { case 0: // something break; case 1: // something else break; } // All other numbers? } // Violates this rule as well, but already emits a compiler warning (\-Wswitch). enum Color { Red, Green, Blue, Yellow }; void f3(enum Color c) { switch (c) { case Red: // We can\(aqt drive for now. break; case Green: // We are allowed to drive. break; } // Other cases missing } .ft P .fi .UNINDENT .UNINDENT .sp The \fI\%rule 6.1.4\fP requires every \fBswitch\fP statement to have at least two \fBcase\fP labels other than a \fIdefault\fP label. Otherwise, the \fBswitch\fP could be better expressed with an \fBif\fP statement. Degenerated \fBswitch\fP statements without any labels are caught as well. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Degenerated switch that could be better written as \(gaif\(ga int i = 42; switch(i) { case 1: // do something here default: // do something else here } // Should rather be the following: if (i == 1) { // do something here } else { // do something here } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // A completely degenerated switch will be diagnosed. int i = 42; switch(i) {} .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B WarnOnMissingElse Boolean flag that activates a warning for missing \fBelse\fP branches. Default is \fIfalse\fP\&. .UNINDENT .SS hicpp\-named\-parameter .sp This check is an alias for \fI\%readability\-named\-parameter\fP\&. .sp Implements \fI\%rule 8.2.1\fP\&. .SS hicpp\-new\-delete\-operators .sp This check is an alias for \fI\%misc\-new\-delete\-overloads\fP\&. Implements \fI\%rule 12.3.1\fP to ensure the \fInew\fP and \fIdelete\fP operators have the correct signature. .SS hicpp\-no\-array\-decay .sp The \fIhicpp\-no\-array\-decay\fP check is an alias, please see \fI\%cppcoreguidelines\-pro\-bounds\-array\-to\-pointer\-decay\fP for more information. It enforces the \fI\%rule 4.1.1\fP\&. .SS hicpp\-no\-assembler .sp Check for assembler statements. No fix is offered. .sp Inline assembler is forbidden by the \fI\%High Integrity C++ Coding Standard\fP as it restricts the portability of code. .SS hicpp\-no\-malloc .sp The \fIhicpp\-no\-malloc\fP check is an alias, please see \fI\%cppcoreguidelines\-no\-malloc\fP for more information. It enforces the \fI\%rule 5.3.2\fP\&. .SS hicpp\-noexcept\-move .sp This check is an alias for \fI\%performance\-noexcept\-move\-constructor\fP\&. Checks \fI\%rule 12.5.4\fP to mark move assignment and move construction \fInoexcept\fP\&. .SS hicpp\-signed\-bitwise .sp Finds uses of bitwise operations on signed integer types, which may lead to undefined or implementation defined behavior. .sp The according rule is defined in the \fI\%High Integrity C++ Standard, Section 5.6.1\fP\&. .SS Options .INDENT 0.0 .TP .B IgnorePositiveIntegerLiterals If this option is set to \fItrue\fP, the check will not warn on bitwise operations with positive integer literals, e.g. \fI~0\fP, \fI2 << 1\fP, etc. Default value is \fIfalse\fP\&. .UNINDENT .SS hicpp\-special\-member\-functions .sp This check is an alias for \fI\%cppcoreguidelines\-special\-member\-functions\fP\&. Checks that special member functions have the correct signature, according to \fI\%rule 12.5.7\fP\&. .SS hicpp\-static\-assert .sp The \fIhicpp\-static\-assert\fP check is an alias, please see \fI\%misc\-static\-assert\fP for more information. It enforces the \fI\%rule 7.1.10\fP\&. .SS hicpp\-undelegated\-constructor .sp This check is an alias for \fI\%bugprone\-undelegated\-constructor\fP\&. Partially implements \fI\%rule 12.4.5\fP to find misplaced constructor calls inside a constructor. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct Ctor { Ctor(); Ctor(int); Ctor(int, int); Ctor(Ctor *i) { // All Ctor() calls result in a temporary object Ctor(); // did you intend to call a delegated constructor? Ctor(0); // did you intend to call a delegated constructor? Ctor(1, 2); // did you intend to call a delegated constructor? foo(); } }; .ft P .fi .UNINDENT .UNINDENT .SS hicpp\-uppercase\-literal\-suffix .sp The hicpp\-uppercase\-literal\-suffix check is an alias, please see \fI\%readability\-uppercase\-literal\-suffix\fP for more information. .SS hicpp\-use\-auto .sp The \fIhicpp\-use\-auto\fP check is an alias, please see \fI\%modernize\-use\-auto\fP for more information. It enforces the \fI\%rule 7.1.8\fP\&. .SS hicpp\-use\-emplace .sp The \fIhicpp\-use\-emplace\fP check is an alias, please see \fI\%modernize\-use\-emplace\fP for more information. It enforces the \fI\%rule 17.4.2\fP\&. .SS hicpp\-use\-equals\-default .sp This check is an alias for \fI\%modernize\-use\-equals\-default\fP\&. Implements \fI\%rule 12.5.1\fP to explicitly default special member functions. .SS hicpp\-use\-equals\-delete .sp This check is an alias for \fI\%modernize\-use\-equals\-delete\fP\&. Implements \fI\%rule 12.5.1\fP to explicitly default or delete special member functions. .SS hicpp\-use\-noexcept .sp The \fIhicpp\-use\-noexcept\fP check is an alias, please see \fI\%modernize\-use\-noexcept\fP for more information. It enforces the \fI\%rule 1.3.5\fP\&. .SS hicpp\-use\-nullptr .sp The \fIhicpp\-use\-nullptr\fP check is an alias, please see \fI\%modernize\-use\-nullptr\fP for more information. It enforces the \fI\%rule 2.5.3\fP\&. .SS hicpp\-use\-override .sp This check is an alias for \fI\%modernize\-use\-override\fP\&. Implements \fI\%rule 10.2.1\fP to declare a virtual function \fIoverride\fP when overriding. .SS hicpp\-vararg .sp The \fIhicpp\-vararg\fP check is an alias, please see \fI\%cppcoreguidelines\-pro\-type\-vararg\fP for more information. It enforces the \fI\%rule 14.1.1\fP\&. .SS linuxkernel\-must\-use\-errs .sp Checks Linux kernel code to see if it uses the results from the functions in \fBlinux/err.h\fP\&. Also checks to see if code uses the results from functions that directly return a value from one of these error functions. .sp This is important in the Linux kernel because \fBERR_PTR\fP, \fBPTR_ERR\fP, \fBIS_ERR\fP, \fBIS_ERR_OR_NULL\fP, \fBERR_CAST\fP, and \fBPTR_ERR_OR_ZERO\fP return values must be checked, since positive pointers and negative error codes are being used in the same context. These functions are marked with \fB__attribute__((warn_unused_result))\fP, but some kernel versions do not have this warning enabled for clang. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C /* Trivial unused call to an ERR function */ PTR_ERR_OR_ZERO(some_function_call()); /* A function that returns ERR_PTR. */ void *fn() { ERR_PTR(\-EINVAL); } /* An invalid use of fn. */ fn(); .ft P .fi .UNINDENT .UNINDENT .SS llvm\-else\-after\-return .sp The llvm\-else\-after\-return check is an alias, please see \fI\%readability\-else\-after\-return\fP for more information. .SS llvm\-header\-guard .sp Finds and fixes header guards that do not adhere to LLVM style. .SS Options .INDENT 0.0 .TP .B HeaderFileExtensions Note: this option is deprecated, it will be removed in \fBclang\-tidy\fP version 19. Please use the global configuration option \fIHeaderFileExtensions\fP\&. .sp A comma\-separated list of filename extensions of header files (the filename extensions should not include \(dq.\(dq prefix). Default is \(dqh,hh,hpp,hxx\(dq. For header files without an extension, use an empty string (if there are no other desired extensions) or leave an empty element in the list. E.g., \(dqh,hh,hpp,hxx,\(dq (note the trailing comma). .UNINDENT .SS llvm\-include\-order .sp Checks the correct order of \fB#includes\fP\&. .sp See \fI\%https://llvm.org/docs/CodingStandards.html#include\-style\fP .SS llvm\-namespace\-comment .sp \fIgoogle\-readability\-namespace\-comments\fP redirects here as an alias for this check. .sp Checks that long namespaces have a closing comment. .sp \fI\%https://llvm.org/docs/CodingStandards.html#namespace\-indentation\fP .sp \fI\%https://google.github.io/styleguide/cppguide.html#Namespaces\fP .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C namespace n1 { void f(); } // becomes namespace n1 { void f(); } // namespace n1 .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B ShortNamespaceLines Requires the closing brace of the namespace definition to be followed by a closing comment if the body of the namespace has more than \fIShortNamespaceLines\fP lines of code. The value is an unsigned integer that defaults to \fI1U\fP\&. .UNINDENT .INDENT 0.0 .TP .B SpacesBeforeComments An unsigned integer specifying the number of spaces before the comment closing a namespace definition. Default is \fI1U\fP\&. .UNINDENT .SS llvm\-prefer\-isa\-or\-dyn\-cast\-in\-conditionals .sp Looks at conditionals and finds and replaces cases of \fBcast<>\fP, which will assert rather than return a null pointer, and \fBdyn_cast<>\fP where the return value is not captured. Additionally, finds and replaces cases that match the pattern \fBvar && isa(var)\fP, where \fBvar\fP is evaluated twice. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Finds these: if (auto x = cast(y)) {} // is replaced by: if (auto x = dyn_cast(y)) {} if (cast(y)) {} // is replaced by: if (isa(y)) {} if (dyn_cast(y)) {} // is replaced by: if (isa(y)) {} if (var && isa(var)) {} // is replaced by: if (isa_and_nonnull(var.foo())) {} // Other cases are ignored, e.g.: if (auto f = cast(y)\->foo()) {} if (cast(y)\->foo()) {} if (X.cast(y)) {} .ft P .fi .UNINDENT .UNINDENT .SS llvm\-prefer\-register\-over\-unsigned .sp Finds historical use of \fBunsigned\fP to hold vregs and physregs and rewrites them to use \fBRegister\fP\&. .sp Currently this works by finding all variables of unsigned integer type whose initializer begins with an implicit cast from \fBRegister\fP to \fBunsigned\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void example(MachineOperand &MO) { unsigned Reg = MO.getReg(); ... } .ft P .fi .UNINDENT .UNINDENT .sp becomes: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void example(MachineOperand &MO) { Register Reg = MO.getReg(); ... } .ft P .fi .UNINDENT .UNINDENT .SS llvm\-qualified\-auto .sp The llvm\-qualified\-auto check is an alias, please see \fI\%readability\-qualified\-auto\fP for more information. .SS llvm\-twine\-local .sp Looks for local \fBTwine\fP variables which are prone to use after frees and should be generally avoided. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static Twine Moo = Twine(\(dqbark\(dq) + \(dqbah\(dq; // becomes static std::string Moo = (Twine(\(dqbark\(dq) + \(dqbah\(dq).str(); .ft P .fi .UNINDENT .UNINDENT .SS llvmlibc\-callee\-namespace .sp Checks all calls resolve to functions within \fB__llvm_libc\fP namespace. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C namespace __llvm_libc { // Allow calls with the fully qualified name. __llvm_libc::strlen(\(dqhello\(dq); // Allow calls to compiler provided functions. (void)__builtin_abs(\-1); // Bare calls are allowed as long as they resolve to the correct namespace. strlen(\(dqworld\(dq); // Disallow calling into functions in the global namespace. ::strlen(\(dq!\(dq); } // namespace __llvm_libc .ft P .fi .UNINDENT .UNINDENT .SS llvmlibc\-implementation\-in\-namespace .sp Checks that all declarations in the llvm\-libc implementation are within the correct namespace. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Correct: implementation inside the correct namespace. namespace __llvm_libc { void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} // Namespaces within __llvm_libc namespace are allowed. namespace inner{ int localVar = 0; } // Functions with C linkage are allowed. extern \(dqC\(dq void str_fuzz(){} } // Incorrect: implementation not in a namespace. void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} // Incorrect: outer most namespace is not correct. namespace something_else { void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} } .ft P .fi .UNINDENT .UNINDENT .SS llvmlibc\-inline\-function\-decl .sp Checks that all implicit and explicit inline functions in header files are tagged with the \fBLIBC_INLINE\fP macro. See the \fI\%libc style guide\fP for more information about this macro. .SS llvmlibc\-restrict\-system\-libc\-headers .sp Finds includes of system libc headers not provided by the compiler within llvm\-libc implementations. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include // Not allowed because it is part of system libc. #include // Allowed because it is provided by the compiler. #include \(dqinternal/stdio.h\(dq // Allowed because it is NOT part of system libc. .ft P .fi .UNINDENT .UNINDENT .sp This check is necessary because accidentally including system libc headers can lead to subtle and hard to detect bugs. For example consider a system libc whose \fBdirent\fP struct has slightly different field ordering than llvm\-libc. While this will compile successfully, this can cause issues during runtime because they are ABI incompatible. .SS Options .INDENT 0.0 .TP .B Includes A string containing a comma separated glob list of allowed include filenames. Similar to the \-checks glob list for running clang\-tidy itself, the two wildcard characters are \fI*\fP and \fI\-\fP, to include and exclude globs, respectively. The default is \fI\-*\fP, which disallows all includes. .sp This can be used to allow known safe includes such as Linux development headers. See \fI\%portability\-restrict\-system\-includes\fP for more details. .UNINDENT .SS misc\-confusable\-identifiers .sp Warn about confusable identifiers, i.e. identifiers that are visually close to each other, but use different Unicode characters. This detects a potential attack described in \fI\%CVE\-2021\-42574\fP\&. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int fo; // Initial character is U+0066 (LATIN SMALL LETTER F). int 𝐟o; // Initial character is U+1D41F (MATHEMATICAL BOLD SMALL F) not U+0066 (LATIN SMALL LETTER F). .ft P .fi .UNINDENT .UNINDENT .SS misc\-const\-correctness .sp This check implements detection of local variables which could be declared as \fBconst\fP but are not. Declaring variables as \fBconst\fP is required or recommended by many coding guidelines, such as: \fI\%ES.25\fP from the C++ Core Guidelines and \fI\%AUTOSAR C++14 Rule A7\-1\-1 (6.7.1 Specifiers)\fP\&. .sp Please note that this check\(aqs analysis is type\-based only. Variables that are not modified but used to create a non\-const handle that might escape the scope are not diagnosed as potential \fBconst\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Declare a variable, which is not \(ga\(gaconst\(ga\(ga ... int i = 42; // but use it as read\-only. This means that \(gai\(ga can be declared \(ga\(gaconst\(ga\(ga. int result = i * i; // Before transformation int const result = i * i; // After transformation .ft P .fi .UNINDENT .UNINDENT .sp The check can analyze values, pointers and references but not (yet) pointees: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Normal values like built\-ins or objects. int potential_const_int = 42; // Before transformation int const potential_const_int = 42; // After transformation int copy_of_value = potential_const_int; MyClass could_be_const; // Before transformation MyClass const could_be_const; // After transformation could_be_const.const_qualified_method(); // References can be declared const as well. int &reference_value = potential_const_int; // Before transformation int const& reference_value = potential_const_int; // After transformation int another_copy = reference_value; // The similar semantics of pointers are not (yet) analyzed. int *pointer_variable = &potential_const_int; // _NO_ \(aqconst int *pointer_variable\(aq suggestion. int last_copy = *pointer_variable; .ft P .fi .UNINDENT .UNINDENT .sp The automatic code transformation is only applied to variables that are declared in single declarations. You may want to prepare your code base with \fI\%readability\-isolate\-declaration\fP first. .sp Note that there is the check \fI\%cppcoreguidelines\-avoid\-non\-const\-global\-variables\fP to enforce \fBconst\fP correctness on all globals. .SS Known Limitations .sp The check does not run on \fIC\fP code. .sp The check will not analyze templated variables or variables that are instantiation dependent. Different instantiations can result in different \fBconst\fP correctness properties and in general it is not possible to find all instantiations of a template. The template might be used differently in an independent translation unit. .sp Pointees can not be analyzed for constness yet. The following code shows this limitation. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Declare a variable that will not be modified. int constant_value = 42; // Declare a pointer to that variable, that does not modify either, but misses \(aqconst\(aq. // Could be \(aqconst int *pointer_to_constant = &constant_value;\(aq int *pointer_to_constant = &constant_value; // Usage: int result = 520 * 120 * (*pointer_to_constant); .ft P .fi .UNINDENT .UNINDENT .sp This limitation affects the capability to add \fBconst\fP to methods which is not possible, too. .SS Options .INDENT 0.0 .TP .B AnalyzeValues (default = true) Enable or disable the analysis of ordinary value variables, like \fBint i = 42;\fP .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C // Warning int i = 42; // No warning int const i = 42; // Warning int a[] = {42, 42, 42}; // No warning int const a[] = {42, 42, 42}; .ft P .fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B AnalyzeReferences (default = true) Enable or disable the analysis of reference variables, like \fBint &ref = i;\fP .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C int i = 42; // Warning int& ref = i; // No warning int const& ref = i; .ft P .fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B WarnPointersAsValues (default = false) This option enables the suggestion for \fBconst\fP of the pointer itself. Pointer values have two possibilities to be \fBconst\fP, the pointer and the value pointing to. .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C int value = 42; // Warning const int * pointer_variable = &value; // No warning const int *const pointer_variable = &value; .ft P .fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B TransformValues (default = true) Provides fixit\-hints for value types that automatically add \fBconst\fP if its a single declaration. .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C // Before int value = 42; // After int const value = 42; // Before int a[] = {42, 42, 42}; // After int const a[] = {42, 42, 42}; // Result is modified later in its life\-time. No diagnostic and fixit hint will be emitted. int result = value * 3; result \-= 10; .ft P .fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B TransformReferences (default = true) Provides fixit\-hints for reference types that automatically add \fBconst\fP if its a single declaration. .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C // This variable could still be a constant. But because there is a non\-const reference to // it, it can not be transformed (yet). int value = 42; // The reference \(aqref_value\(aq is not modified and can be made \(aqconst int &ref_value = value;\(aq // Before int &ref_value = value; // After int const &ref_value = value; // Result is modified later in its life\-time. No diagnostic and fixit hint will be emitted. int result = ref_value * 3; result \-= 10; .ft P .fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B TransformPointersAsValues (default = false) Provides fixit\-hints for pointers if their pointee is not changed. This does not analyze if the value\-pointed\-to is unchanged! .sp Requires \(aqWarnPointersAsValues\(aq to be \(aqtrue\(aq. .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C int value = 42; // Before const int * pointer_variable = &value; // After const int *const pointer_variable = &value; // Before const int * a[] = {&value, &value}; // After const int *const a[] = {&value, &value}; // Before int *ptr_value = &value; // After int *const ptr_value = &value; int result = 100 * (*ptr_value); // Does not modify the pointer itself. // This modification of the pointee is still allowed and not diagnosed. *ptr_value = 0; // The following pointer may not become a \(aqint *const\(aq. int *changing_pointee = &value; changing_pointee = &result; .ft P .fi .UNINDENT .UNINDENT .UNINDENT .SS misc\-definitions\-in\-headers .sp Finds non\-extern non\-inline function and variable definitions in header files, which can lead to potential ODR violations in case these headers are included from multiple translation units. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Foo.h int a = 1; // Warning: variable definition. extern int d; // OK: extern variable. namespace N { int e = 2; // Warning: variable definition. } // Warning: variable definition. const char* str = \(dqfoo\(dq; // OK: internal linkage variable definitions are ignored for now. // Although these might also cause ODR violations, we can be less certain and // should try to keep the false\-positive rate down. static int b = 1; const int c = 1; const char* const str2 = \(dqfoo\(dq; constexpr int k = 1; namespace { int x = 1; } // Warning: function definition. int g() { return 1; } // OK: inline function definition is allowed to be defined multiple times. inline int e() { return 1; } class A { public: int f1() { return 1; } // OK: implicitly inline member function definition is allowed. int f2(); static int d; }; // Warning: not an inline member function definition. int A::f2() { return 1; } // OK: class static data member declaration is allowed. int A::d = 1; // OK: function template is allowed. template T f3() { T a = 1; return a; } // Warning: full specialization of a function template is not allowed. template <> int f3() { int a = 1; return a; } template struct B { void f1(); }; // OK: member function definition of a class template is allowed. template void B::f1() {} class CE { constexpr static int i = 5; // OK: inline variable definition. }; inline int i = 5; // OK: inline variable definition. constexpr int f10() { return 0; } // OK: constexpr function implies inline. // OK: C++14 variable templates are inline. template constexpr T pi = T(3.1415926L); .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B HeaderFileExtensions Note: this option is deprecated, it will be removed in \fBclang\-tidy\fP version 19. Please use the global configuration option \fIHeaderFileExtensions\fP\&. .sp A comma\-separated list of filename extensions of header files (the filename extensions should not include \(dq.\(dq prefix). Default is \(dqh,hh,hpp,hxx\(dq. For header files without an extension, use an empty string (if there are no other desired extensions) or leave an empty element in the list. E.g., \(dqh,hh,hpp,hxx,\(dq (note the trailing comma). .UNINDENT .INDENT 0.0 .TP .B UseHeaderFileExtension Note: this option is deprecated, it will be removed in \fBclang\-tidy\fP version 19. The check will unconditionally use the global option \fIHeaderFileExtensions\fP\&. .sp When \fItrue\fP, the check will use the file extension to distinguish header files. Default is \fItrue\fP\&. .UNINDENT .SS misc\-header\-include\-cycle .sp Check detects cyclic \fB#include\fP dependencies between user\-defined headers. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Header A.hpp #pragma once #include \(dqB.hpp\(dq // Header B.hpp #pragma once #include \(dqC.hpp\(dq // Header C.hpp #pragma once #include \(dqA.hpp\(dq // Include chain: A\->B\->C\->A .ft P .fi .UNINDENT .UNINDENT .sp Header files are a crucial part of many C++ programs as they provide a way to organize declarations and definitions shared across multiple source files. However, header files can also create problems when they become entangled in complex dependency cycles. Such cycles can cause issues with compilation times, unnecessary rebuilds, and make it harder to understand the overall structure of the code. .sp To address these issues, a check has been developed to detect cyclic dependencies between header files, also known as \(dqinclude cycles\(dq. An include cycle occurs when a header file \fIA\fP includes header file \fIB\fP, and \fIB\fP (or any subsequent included header file) includes back header file \fIA\fP, resulting in a circular dependency cycle. .sp This check operates at the preprocessor level and specifically analyzes user\-defined headers and their dependencies. It focuses solely on detecting include cycles while disregarding other types or function dependencies. This specialized analysis helps identify and prevent issues related to header file organization. .sp By detecting include cycles early in the development process, developers can identify and resolve these issues before they become more difficult and time\-consuming to fix. This can lead to faster compile times, improved code quality, and a more maintainable codebase overall. Additionally, by ensuring that header files are organized in a way that avoids cyclic dependencies, developers can make their code easier to understand and modify over time. .sp It\(aqs worth noting that only user\-defined headers their dependencies are analyzed, System includes such as standard library headers and third\-party library headers are excluded. System includes are usually well\-designed and free of include cycles, and ignoring them helps to focus on potential issues within the project\(aqs own codebase. This limitation doesn\(aqt diminish the ability to detect \fB#include\fP cycles within the analyzed code. .sp Developers should carefully review any warnings or feedback provided by this solution. While the analysis aims to identify and prevent include cycles, there may be situations where exceptions or modifications are necessary. It\(aqs important to exercise judgment and consider the specific context of the codebase when making adjustments. .SS Options .INDENT 0.0 .TP .B IgnoredFilesList Provides a way to exclude specific files/headers from the warnings raised by a check. This can be achieved by specifying a semicolon\-separated list of regular expressions or filenames. This option can be used as an alternative to \fB//NOLINT\fP when using it is not possible. The default value of this option is an empty string, indicating that no files are ignored by default. .UNINDENT .SS misc\-include\-cleaner .sp Checks for unused and missing includes. Generates findings only for the main file of a translation unit. Findings correspond to \fI\%https://clangd.llvm.org/design/include\-cleaner\fP\&. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // foo.h class Foo{}; // bar.h #include \(dqbaz.h\(dq class Bar{}; // baz.h class Baz{}; // main.cc #include \(dqbar.h\(dq // OK: uses class Bar from bar.h #include \(dqfoo.h\(dq // warning: unused include \(dqfoo.h\(dq Bar bar; Baz baz; // warning: missing include \(dqbaz.h\(dq .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreHeaders A semicolon\-separated list of regexes to disable insertion/removal of header files that match this regex as a suffix. E.g., \fIfoo/.*\fP disables insertion/removal for all headers under the directory \fIfoo\fP\&. By default, no headers will be ignored. .UNINDENT .SS misc\-misleading\-bidirectional .sp Warn about unterminated bidirectional unicode sequence, detecting potential attack as described in the \fI\%Trojan Source\fP attack. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include int main() { bool isAdmin = false; /*‮ } ⁦if (isAdmin)⁩ ⁦ begin admins only */ std::cout << \(dqYou are an admin.\en\(dq; /* end admins only ‮ { ⁦*/ return 0; } .ft P .fi .UNINDENT .UNINDENT .SS misc\-misleading\-identifier .sp Finds identifiers that contain Unicode characters with right\-to\-left direction, which can be confusing as they may change the understanding of a whole statement line, as described in \fI\%Trojan Source\fP\&. .sp An example of such misleading code follows: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include short int א = (short int)0; short int ג = (short int)12345; int main() { int א = ג; // a local variable, set to zero? printf(\(dqג is %d\en\(dq, ג); printf(\(dqא is %d\en\(dq, א); } .ft P .fi .UNINDENT .UNINDENT .SS misc\-misplaced\-const .sp This check diagnoses when a \fBconst\fP qualifier is applied to a \fBtypedef\fP/ \fBusing\fP to a pointer type rather than to the pointee, because such constructs are often misleading to developers because the \fBconst\fP applies to the pointer rather than the pointee. .sp For instance, in the following code, the resulting type is \fBint * const\fP rather than \fBconst int *\fP: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C typedef int *int_ptr; void f(const int_ptr ptr) { *ptr = 0; // potentially quite unexpectedly the int can be modified here ptr = 0; // does not compile } .ft P .fi .UNINDENT .UNINDENT .sp The check does not diagnose when the underlying \fBtypedef\fP/\fBusing\fP type is a pointer to a \fBconst\fP type or a function pointer type. This is because the \fBconst\fP qualifier is less likely to be mistaken because it would be redundant (or disallowed) on the underlying pointee type. .SS misc\-new\-delete\-overloads .sp \fIcert\-dcl54\-cpp\fP redirects here as an alias for this check. .sp The check flags overloaded operator \fBnew()\fP and operator \fBdelete()\fP functions that do not have a corresponding free store function defined within the same scope. For instance, the check will flag a class implementation of a non\-placement operator \fBnew()\fP when the class does not also define a non\-placement operator \fBdelete()\fP function as well. .sp The check does not flag implicitly\-defined operators, deleted or private operators, or placement operators. .sp This check corresponds to CERT C++ Coding Standard rule \fI\%DCL54\-CPP. Overload allocation and deallocation functions as a pair in the same scope\fP\&. .SS misc\-no\-recursion .sp Finds strongly connected functions (by analyzing the call graph for SCC\(aqs (Strongly Connected Components) that are loops), diagnoses each function in the cycle, and displays one example of a possible call graph loop (recursion). .sp References: .INDENT 0.0 .IP \(bu 2 CERT C++ Coding Standard rule \fI\%DCL56\-CPP. Avoid cycles during initialization of static objects\fP\&. .IP \(bu 2 JPL Institutional Coding Standard for the C Programming Language (JPL DOCID D\-60411) rule \fI2.4 Do not use direct or indirect recursion\fP\&. .IP \(bu 2 OpenCL Specification, Version 1.2 rule \fI\%6.9 Restrictions: i. Recursion is not supported.\fP\&. .UNINDENT .sp Limitations: .INDENT 0.0 .IP \(bu 2 The check does not handle calls done through function pointers .IP \(bu 2 The check does not handle C++ destructors .UNINDENT .SS misc\-non\-copyable\-objects .sp \fIcert\-fio38\-c\fP redirects here as an alias for this check. .sp The check flags dereferences and non\-pointer declarations of objects that are not meant to be passed by value, such as C FILE objects or POSIX \fBpthread_mutex_t\fP objects. .sp This check corresponds to CERT C++ Coding Standard rule \fI\%FIO38\-C. Do not copy a FILE object\fP\&. .SS misc\-non\-private\-member\-variables\-in\-classes .sp \fIcppcoreguidelines\-non\-private\-member\-variables\-in\-classes\fP redirects here as an alias for this check. .sp Finds classes that contain non\-static data members in addition to user\-declared non\-static member functions and diagnose all data members declared with a non\-\fBpublic\fP access specifier. The data members should be declared as \fBprivate\fP and accessed through member functions instead of exposed to derived classes or class consumers. .SS Options .INDENT 0.0 .TP .B IgnoreClassesWithAllMemberVariablesBeingPublic Allows to completely ignore classes if \fBall\fP the member variables in that class a declared with a \fBpublic\fP access specifier. .UNINDENT .INDENT 0.0 .TP .B IgnorePublicMemberVariables Allows to ignore (not diagnose) \fBall\fP the member variables declared with a \fBpublic\fP access specifier. .UNINDENT .SS misc\-redundant\-expression .sp Detect redundant expressions which are typically errors due to copy\-paste. .sp Depending on the operator expressions may be .INDENT 0.0 .IP \(bu 2 redundant, .IP \(bu 2 always \fBtrue\fP, .IP \(bu 2 always \fBfalse\fP, .IP \(bu 2 always a constant (zero or one). .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C ((x+1) | (x+1)) // (x+1) is redundant (p\->x == p\->x) // always true (p\->x < p\->x) // always false (speed \- speed + 1 == 12) // speed \- speed is always zero .ft P .fi .UNINDENT .UNINDENT .SS misc\-static\-assert .sp \fIcert\-dcl03\-c\fP redirects here as an alias for this check. .sp Replaces \fBassert()\fP with \fBstatic_assert()\fP if the condition is evaluable at compile time. .sp The condition of \fBstatic_assert()\fP is evaluated at compile time which is safer and more efficient. .SS misc\-throw\-by\-value\-catch\-by\-reference .sp \fIcert\-err09\-cpp\fP redirects here as an alias for this check. \fIcert\-err61\-cpp\fP redirects here as an alias for this check. .sp Finds violations of the rule \(dqThrow by value, catch by reference\(dq presented for example in \(dqC++ Coding Standards\(dq by H. Sutter and A. Alexandrescu, as well as the CERT C++ Coding Standard rule \fI\%ERR61\-CPP. Catch exceptions by lvalue reference\fP\&. .INDENT 0.0 .TP .B Exceptions: .INDENT 7.0 .IP \(bu 2 Throwing string literals will not be flagged despite being a pointer. They are not susceptible to slicing and the usage of string literals is idiomatic. .IP \(bu 2 Catching character pointers (\fBchar\fP, \fBwchar_t\fP, unicode character types) will not be flagged to allow catching string literals. .IP \(bu 2 Moved named values will not be flagged as not throwing an anonymous temporary. In this case we can be sure that the user knows that the object can\(aqt be accessed outside catch blocks handling the error. .IP \(bu 2 Throwing function parameters will not be flagged as not throwing an anonymous temporary. This allows helper functions for throwing. .IP \(bu 2 Re\-throwing caught exception variables will not be flagged as not throwing an anonymous temporary. Although this can usually be done by just writing \fBthrow;\fP it happens often enough in real code. .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B CheckThrowTemporaries Triggers detection of violations of the CERT recommendation ERR09\-CPP. Throw anonymous temporaries. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnOnLargeObject Also warns for any large, trivial object caught by value. Catching a large object by value is not dangerous but affects the performance negatively. The maximum size of an object allowed to be caught without warning can be set using the \fIMaxSize\fP option. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B MaxSize Determines the maximum size of an object allowed to be caught without warning. Only applicable if \fI\%WarnOnLargeObject\fP is set to \fItrue\fP\&. If the option is set by the user to \fIstd::numeric_limits::max()\fP then it reverts to the default value. Default is the size of \fIsize_t\fP\&. .UNINDENT .SS misc\-unconventional\-assign\-operator .sp Finds declarations of assign operators with the wrong return and/or argument types and definitions with good return type but wrong \fBreturn\fP statements. .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 The return type must be \fBClass&\fP\&. .IP \(bu 2 The assignment may be from the class type by value, const lvalue reference, non\-const rvalue reference, or from a completely different type (e.g. \fBint\fP). .IP \(bu 2 Private and deleted operators are ignored. .IP \(bu 2 The operator must always return \fB*this\fP\&. .UNINDENT .UNINDENT .UNINDENT .SS misc\-uniqueptr\-reset\-release .sp Find and replace \fBunique_ptr::reset(release())\fP with \fBstd::move()\fP\&. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::unique_ptr x, y; x.reset(y.release()); \-> x = std::move(y); .ft P .fi .UNINDENT .UNINDENT .sp If \fBy\fP is already rvalue, \fBstd::move()\fP is not added. \fBx\fP and \fBy\fP can also be \fBstd::unique_ptr*\fP\&. .SS Options .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .SS misc\-unused\-alias\-decls .sp Finds unused namespace alias declarations. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C namespace my_namespace { class C {}; } namespace unused_alias = ::my_namespace; .ft P .fi .UNINDENT .UNINDENT .SS misc\-unused\-parameters .sp Finds unused function parameters. Unused parameters may signify a bug in the code (e.g. when a different parameter is used instead). The suggested fixes either comment parameter name out or remove the parameter completely, if all callers of the function are in the same translation unit and can be updated. .sp The check is similar to the \fB\-Wunused\-parameter\fP compiler diagnostic and can be used to prepare a codebase to enabling of that diagnostic. By default the check is more permissive (see \fI\%StrictMode\fP). .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void a(int i) { /*some code that doesn\(aqt use \(gai\(ga*/ } // becomes void a(int /*i*/) { /*some code that doesn\(aqt use \(gai\(ga*/ } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static void staticFunctionA(int i); static void staticFunctionA(int i) { /*some code that doesn\(aqt use \(gai\(ga*/ } // becomes static void staticFunctionA() static void staticFunctionA() { /*some code that doesn\(aqt use \(gai\(ga*/ } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B StrictMode When \fIfalse\fP (default value), the check will ignore trivially unused parameters, i.e. when the corresponding function has an empty body (and in case of constructors \- no constructor initializers). When the function body is empty, an unused parameter is unlikely to be unnoticed by a human reader, and there\(aqs basically no place for a bug to hide. .UNINDENT .INDENT 0.0 .TP .B IgnoreVirtual Determines whether virtual method parameters should be inspected. Set to \fItrue\fP to ignore them. Default is \fIfalse\fP\&. .UNINDENT .SS misc\-unused\-using\-decls .sp Finds unused \fBusing\fP declarations. .sp Unused \fBusing\(ga\fP declarations in header files will not be diagnosed since these using declarations are part of the header\(aqs public API. Allowed header file extensions can be configured via the \fIHeaderFileExtensions\fP option (see below). .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // main.cpp namespace n { class C; } using n::C; // Never actually used. .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B HeaderFileExtensions Note: this option is deprecated, it will be removed in \fBclang\-tidy\fP version 19. Please use the global configuration option \fIHeaderFileExtensions\fP\&. .sp A semicolon\-separated list of filename extensions of header files (the filename extensions should not include \(dq.\(dq prefix). Default is \(dqh,hh,hpp,hxx\(dq. For extension\-less header files, use an empty string or leave an empty string between \(dq,\(dq if there are other filename extensions. .UNINDENT .SS misc\-use\-anonymous\-namespace .sp Finds instances of \fBstatic\fP functions or variables declared at global scope that could instead be moved into an anonymous namespace. .sp Anonymous namespaces are the \(dqsuperior alternative\(dq according to the C++ Standard. \fBstatic\fP was proposed for deprecation, but later un\-deprecated to keep C compatibility [1]. \fBstatic\fP is an overloaded term with different meanings in different contexts, so it can create confusion. .sp The following uses of \fBstatic\fP will \fInot\fP be diagnosed: .INDENT 0.0 .IP \(bu 2 Functions or variables in header files, since anonymous namespaces in headers is considered an antipattern. Allowed header file extensions can be configured via the \fIHeaderFileExtensions\fP option (see below). .IP \(bu 2 \fBconst\fP or \fBconstexpr\fP variables, since they already have implicit internal linkage in C++. .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Bad static void foo(); static int x; // Good namespace { void foo(); int x; } // namespace .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B HeaderFileExtensions Note: this option is deprecated, it will be removed in \fBclang\-tidy\fP version 19. Please use the global configuration option \fIHeaderFileExtensions\fP\&. .sp A semicolon\-separated list of filename extensions of header files (the filename extensions should not include \(dq.\(dq prefix). Default is \(dq;h;hh;hpp;hxx\(dq. For extension\-less header files, using an empty string or leaving an empty string between \(dq;\(dq if there are other filename extensions. .UNINDENT .sp [1] \fI\%Undeprecating static\fP .SS modernize\-avoid\-bind .sp The check finds uses of \fBstd::bind\fP and \fBboost::bind\fP and replaces them with lambdas. Lambdas will use value\-capture unless reference capture is explicitly requested with \fBstd::ref\fP or \fBboost::ref\fP\&. .sp It supports arbitrary callables including member functions, function objects, and free functions, and all variations thereof. Anything that you can pass to the first argument of \fBbind\fP should be diagnosable. Currently, the only known case where a fix\-it is unsupported is when the same placeholder is specified multiple times in the parameter list. .sp Given: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int add(int x, int y) { return x + y; } .ft P .fi .UNINDENT .UNINDENT .sp Then: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f() { int x = 2; auto clj = std::bind(add, x, _1); } .ft P .fi .UNINDENT .UNINDENT .sp is replaced by: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f() { int x = 2; auto clj = [=](auto && arg1) { return add(x, arg1); }; } .ft P .fi .UNINDENT .UNINDENT .sp \fBstd::bind\fP can be hard to read and can result in larger object files and binaries due to type information that will not be produced by equivalent lambdas. .SS Options .INDENT 0.0 .TP .B PermissiveParameterList If the option is set to \fItrue\fP, the check will append \fBauto&&...\fP to the end of every placeholder parameter list. Without this, it is possible for a fix\-it to perform an incorrect transformation in the case where the result of the \fBbind\fP is used in the context of a type erased functor such as \fBstd::function\fP which allows mismatched arguments. For example: .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int add(int x, int y) { return x + y; } int foo() { std::function ignore_args = std::bind(add, 2, 2); return ignore_args(3, 3); } .ft P .fi .UNINDENT .UNINDENT .sp is valid code, and returns \fI4\fP\&. The actual values passed to \fBignore_args\fP are simply ignored. Without \fBPermissiveParameterList\fP, this would be transformed into .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int add(int x, int y) { return x + y; } int foo() { std::function ignore_args = [] { return add(2, 2); } return ignore_args(3, 3); } .ft P .fi .UNINDENT .UNINDENT .sp which will \fInot\fP compile, since the lambda does not contain an \fBoperator()\fP that accepts 2 arguments. With permissive parameter list, it instead generates .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int add(int x, int y) { return x + y; } int foo() { std::function ignore_args = [](auto&&...) { return add(2, 2); } return ignore_args(3, 3); } .ft P .fi .UNINDENT .UNINDENT .sp which is correct. .sp This check requires using C++14 or higher to run. .SS modernize\-avoid\-c\-arrays .sp \fIcppcoreguidelines\-avoid\-c\-arrays\fP redirects here as an alias for this check. .sp \fIhicpp\-avoid\-c\-arrays\fP redirects here as an alias for this check. .sp Finds C\-style array types and recommend to use \fBstd::array<>\fP / \fBstd::vector<>\fP\&. All types of C arrays are diagnosed. .sp However, fix\-it are potentially dangerous in header files and are therefore not emitted right now. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int a[] = {1, 2}; // warning: do not declare C\-style arrays, use std::array<> instead int b[1]; // warning: do not declare C\-style arrays, use std::array<> instead void foo() { int c[b[0]]; // warning: do not declare C VLA arrays, use std::vector<> instead } template class array { T d[Size]; // warning: do not declare C\-style arrays, use std::array<> instead int e[1]; // warning: do not declare C\-style arrays, use std::array<> instead }; array d; // warning: do not declare C\-style arrays, use std::array<> instead using k = int[4]; // warning: do not declare C\-style arrays, use std::array<> instead .ft P .fi .UNINDENT .UNINDENT .sp However, the \fBextern \(dqC\(dq\fP code is ignored, since it is common to share such headers between C code, and C++ code. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Some header extern \(dqC\(dq { int f[] = {1, 2}; // not diagnosed int j[1]; // not diagnosed inline void bar() { { int j[j[0]]; // not diagnosed } } } .ft P .fi .UNINDENT .UNINDENT .sp Similarly, the \fBmain()\fP function is ignored. Its second and third parameters can be either \fBchar* argv[]\fP or \fBchar** argv\fP, but cannot be \fBstd::array<>\fP\&. .SS modernize\-concat\-nested\-namespaces .sp Checks for use of nested namespaces such as \fBnamespace a { namespace b { ... } }\fP and suggests changing to the more concise syntax introduced in C++17: \fBnamespace a::b { ... }\fP\&. Inline namespaces are not modified. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C namespace n1 { namespace n2 { void t(); } } namespace n3 { namespace n4 { namespace n5 { void t(); } } namespace n6 { namespace n7 { void t(); } } } // in c++20 namespace n8 { inline namespace n9 { void t(); } } .ft P .fi .UNINDENT .UNINDENT .sp Will be modified to: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C namespace n1::n2 { void t(); } namespace n3 { namespace n4::n5 { void t(); } namespace n6::n7 { void t(); } } // in c++20 namespace n8::inline n9 { void t(); } .ft P .fi .UNINDENT .UNINDENT .SS modernize\-deprecated\-headers .sp Some headers from C library were deprecated in C++ and are no longer welcome in C++ codebases. Some have no effect in C++. For more details refer to the C++ 14 Standard [depr.c.headers] section. .sp This check replaces C standard library headers with their C++ alternatives and removes redundant ones. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // C++ source file... #include #include // becomes #include // No \(aqstdbool.h\(aq here. .ft P .fi .UNINDENT .UNINDENT .sp Important note: the Standard doesn\(aqt guarantee that the C++ headers declare all the same functions in the global namespace. The check in its current form can break the code that uses library symbols from the global namespace. .INDENT 0.0 .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP // deprecated since C++11 .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP // deprecated since C++11 .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP // deprecated since C++11 .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .UNINDENT .sp If the specified standard is older than C++11 the check will only replace headers deprecated before C++11, otherwise \-\- every header that appeared in the previous list. .sp These headers don\(aqt have effect in C++: .INDENT 0.0 .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .IP \(bu 2 \fI\fP .UNINDENT .sp The checker ignores \fIinclude\fP directives within \fIextern \(dqC\(dq { ... }\fP blocks, since a library might want to expose some API for C and C++ libraries. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // C++ source file... extern \(dqC\(dq { #include // Left intact. #include // Left intact. } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B CheckHeaderFile \fIclang\-tidy\fP cannot know if the header file included by the currently analyzed C++ source file is not included by any other C source files. Hence, to omit false\-positives and wrong fixit\-hints, we ignore emitting reports into header files. One can set this option to \fItrue\fP if they know that the header files in the project are only used by C++ source file. Default is \fIfalse\fP\&. .UNINDENT .SS modernize\-deprecated\-ios\-base\-aliases .sp Detects usage of the deprecated member types of \fBstd::ios_base\fP and replaces those that have a non\-deprecated equivalent. .TS center; |l|l|. _ T{ Deprecated member type T} T{ Replacement T} _ T{ \fBstd::ios_base::io_state\fP T} T{ \fBstd::ios_base::iostate\fP T} _ T{ \fBstd::ios_base::open_mode\fP T} T{ \fBstd::ios_base::openmode\fP T} _ T{ \fBstd::ios_base::seek_dir\fP T} T{ \fBstd::ios_base::seekdir\fP T} _ T{ \fBstd::ios_base::streamoff\fP T} T{ T} _ T{ \fBstd::ios_base::streampos\fP T} T{ T} _ .TE .SS modernize\-loop\-convert .sp This check converts \fBfor(...; ...; ...)\fP loops to use the new range\-based loops in C++11. .sp Three kinds of loops can be converted: .INDENT 0.0 .IP \(bu 2 Loops over statically allocated arrays. .IP \(bu 2 Loops over containers, using iterators. .IP \(bu 2 Loops over array\-like containers, using \fBoperator[]\fP and \fBat()\fP\&. .UNINDENT .SS MinConfidence option .SS risky .sp In loops where the container expression is more complex than just a reference to a declared expression (a variable, function, enum, etc.), and some part of it appears elsewhere in the loop, we lower our confidence in the transformation due to the increased risk of changing semantics. Transformations for these loops are marked as \fIrisky\fP, and thus will only be converted if the minimum required confidence level is set to \fIrisky\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int arr[10][20]; int l = 5; for (int j = 0; j < 20; ++j) int k = arr[l][j] + l; // using l outside arr[l] is considered risky for (int i = 0; i < obj.getVector().size(); ++i) obj.foo(10); // using \(aqobj\(aq is considered risky .ft P .fi .UNINDENT .UNINDENT .sp See \fI\%Range\-based loops evaluate end() only once\fP for an example of an incorrect transformation when the minimum required confidence level is set to \fIrisky\fP\&. .SS reasonable (Default) .sp If a loop calls \fB\&.end()\fP or \fB\&.size()\fP after each iteration, the transformation for that loop is marked as \fIreasonable\fP, and thus will be converted if the required confidence level is set to \fIreasonable\fP (default) or lower. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // using size() is considered reasonable for (int i = 0; i < container.size(); ++i) cout << container[i]; .ft P .fi .UNINDENT .UNINDENT .SS safe .sp Any other loops that do not match the above criteria to be marked as \fIrisky\fP or \fIreasonable\fP are marked \fIsafe\fP, and thus will be converted if the required confidence level is set to \fIsafe\fP or lower. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int arr[] = {1,2,3}; for (int i = 0; i < 3; ++i) cout << arr[i]; .ft P .fi .UNINDENT .UNINDENT .SS Example .sp Original: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const int N = 5; int arr[] = {1,2,3,4,5}; vector v; v.push_back(1); v.push_back(2); v.push_back(3); // safe conversion for (int i = 0; i < N; ++i) cout << arr[i]; // reasonable conversion for (vector::iterator it = v.begin(); it != v.end(); ++it) cout << *it; // reasonable conversion for (int i = 0; i < v.size(); ++i) cout << v[i]; .ft P .fi .UNINDENT .UNINDENT .sp After applying the check with minimum confidence level set to \fIreasonable\fP (default): .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const int N = 5; int arr[] = {1,2,3,4,5}; vector v; v.push_back(1); v.push_back(2); v.push_back(3); // safe conversion for (auto & elem : arr) cout << elem; // reasonable conversion for (auto & elem : v) cout << elem; // reasonable conversion for (auto & elem : v) cout << elem; .ft P .fi .UNINDENT .UNINDENT .SS Reverse Iterator Support .sp The converter is also capable of transforming iterator loops which use \fBrbegin\fP and \fBrend\fP for looping backwards over a container. Out of the box this will automatically happen in C++20 mode using the \fBranges\fP library, however the check can be configured to work without C++20 by specifying a function to reverse a range and optionally the header file where that function lives. .INDENT 0.0 .TP .B UseCxx20ReverseRanges When set to true convert loops when in C++20 or later mode using \fBstd::ranges::reverse_view\fP\&. Default value is \fBtrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B MakeReverseRangeFunction Specify the function used to reverse an iterator pair, the function should accept a class with \fBrbegin\fP and \fBrend\fP methods and return a class with \fBbegin\fP and \fBend\fP methods that call the \fBrbegin\fP and \fBrend\fP methods respectively. Common examples are \fBranges::reverse_view\fP and \fBllvm::reverse\fP\&. Default value is an empty string. .UNINDENT .INDENT 0.0 .TP .B MakeReverseRangeHeader Specifies the header file where \fI\%MakeReverseRangeFunction\fP is declared. For the previous examples this option would be set to \fBrange/v3/view/reverse.hpp\fP and \fBllvm/ADT/STLExtras.h\fP respectively. If this is an empty string and \fI\%MakeReverseRangeFunction\fP is set, the check will proceed on the assumption that the function is already available in the translation unit. This can be wrapped in angle brackets to signify to add the include as a system include. Default value is an empty string. .UNINDENT .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .SS Limitations .sp There are certain situations where the tool may erroneously perform transformations that remove information and change semantics. Users of the tool should be aware of the behavior and limitations of the check outlined by the cases below. .SS Comments inside loop headers .sp Comments inside the original loop header are ignored and deleted when transformed. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C for (int i = 0; i < N; /* This will be deleted */ ++i) { } .ft P .fi .UNINDENT .UNINDENT .SS Range\-based loops evaluate end() only once .sp The C++11 range\-based for loop calls \fB\&.end()\fP only once during the initialization of the loop. If in the original loop \fB\&.end()\fP is called after each iteration the semantics of the transformed loop may differ. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // The following is semantically equivalent to the C++11 range\-based for loop, // therefore the semantics of the header will not change. for (iterator it = container.begin(), e = container.end(); it != e; ++it) { } // Instead of calling .end() after each iteration, this loop will be // transformed to call .end() only once during the initialization of the loop, // which may affect semantics. for (iterator it = container.begin(); it != container.end(); ++it) { } .ft P .fi .UNINDENT .UNINDENT .sp As explained above, calling member functions of the container in the body of the loop is considered \fIrisky\fP\&. If the called member function modifies the container the semantics of the converted loop will differ due to \fB\&.end()\fP being called only once. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bool flag = false; for (vector::iterator it = vec.begin(); it != vec.end(); ++it) { // Add a copy of the first element to the end of the vector. if (!flag) { // This line makes this transformation \(aqrisky\(aq. vec.push_back(*it); flag = true; } cout << *it; } .ft P .fi .UNINDENT .UNINDENT .sp The original code above prints out the contents of the container including the newly added element while the converted loop, shown below, will only print the original contents and not the newly added element. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bool flag = false; for (auto & elem : vec) { // Add a copy of the first element to the end of the vector. if (!flag) { // This line makes this transformation \(aqrisky\(aq vec.push_back(elem); flag = true; } cout << elem; } .ft P .fi .UNINDENT .UNINDENT .sp Semantics will also be affected if \fB\&.end()\fP has side effects. For example, in the case where calls to \fB\&.end()\fP are logged the semantics will change in the transformed loop if \fB\&.end()\fP was originally called after each iteration. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C iterator end() { num_of_end_calls++; return container.end(); } .ft P .fi .UNINDENT .UNINDENT .SS Overloaded operator\->() with side effects .sp Similarly, if \fBoperator\->()\fP was overloaded to have side effects, such as logging, the semantics will change. If the iterator\(aqs \fBoperator\->()\fP was used in the original loop it will be replaced with \fB.\fP instead due to the implicit dereference as part of the range\-based for loop. Therefore any side effect of the overloaded \fBoperator\->()\fP will no longer be performed. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C for (iterator it = c.begin(); it != c.end(); ++it) { it\->func(); // Using operator\->() } // Will be transformed to: for (auto & elem : c) { elem.func(); // No longer using operator\->() } .ft P .fi .UNINDENT .UNINDENT .SS Pointers and references to containers .sp While most of the check\(aqs risk analysis is dedicated to determining whether the iterator or container was modified within the loop, it is possible to circumvent the analysis by accessing and modifying the container through a pointer or reference. .sp If the container were directly used instead of using the pointer or reference the following transformation would have only been applied at the \fIrisky\fP level since calling a member function of the container is considered \fIrisky\fP\&. The check cannot identify expressions associated with the container that are different than the one used in the loop header, therefore the transformation below ends up being performed at the \fIsafe\fP level. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C vector vec; vector *ptr = &vec; vector &ref = vec; for (vector::iterator it = vec.begin(), e = vec.end(); it != e; ++it) { if (!flag) { // Accessing and modifying the container is considered risky, but the risk // level is not raised here. ptr\->push_back(*it); ref.push_back(*it); flag = true; } } .ft P .fi .UNINDENT .UNINDENT .SS OpenMP .sp As range\-based for loops are only available since OpenMP 5, this check should not be used on code with a compatibility requirement of OpenMP prior to version 5. It is \fBintentional\fP that this check does not make any attempts to exclude incorrect diagnostics on OpenMP for loops prior to OpenMP 5. .sp To prevent this check to be applied (and to break) OpenMP for loops but still be applied to non\-OpenMP for loops the usage of \fBNOLINT\fP (see \fI\%Suppressing Undesired Diagnostics\fP) on the specific for loops is recommended. .SS modernize\-macro\-to\-enum .sp Replaces groups of adjacent macros with an unscoped anonymous enum. Using an unscoped anonymous enum ensures that everywhere the macro token was used previously, the enumerator name may be safely used. .sp This check can be used to enforce the C++ core guideline \fI\%Enum.1: Prefer enumerations over macros\fP, within the constraints outlined below. .sp Potential macros for replacement must meet the following constraints: .INDENT 0.0 .IP \(bu 2 Macros must expand only to integral literal tokens or expressions of literal tokens. The expression may contain any of the unary operators \fB\-\fP, \fB+\fP, \fB~\fP or \fB!\fP, any of the binary operators \fB,\fP, \fB\-\fP, \fB+\fP, \fB*\fP, \fB/\fP, \fB%\fP, \fB&\fP, \fB|\fP, \fB^\fP, \fB<\fP, \fB>\fP, \fB<=\fP, \fB>=\fP, \fB==\fP, \fB!=\fP, \fB||\fP, \fB&&\fP, \fB<<\fP, \fB>>\fP or \fB<=>\fP, the ternary operator \fB?:\fP and its \fI\%GNU extension\fP\&. Parenthesized expressions are also recognized. This recognizes most valid expressions. In particular, expressions with the \fBsizeof\fP operator are not recognized. .IP \(bu 2 Macros must be defined on sequential source file lines, or with only comment lines in between macro definitions. .IP \(bu 2 Macros must all be defined in the same source file. .IP \(bu 2 Macros must not be defined within a conditional compilation block. (Conditional include guards are exempt from this constraint.) .IP \(bu 2 Macros must not be defined adjacent to other preprocessor directives. .IP \(bu 2 Macros must not be used in any conditional preprocessing directive. .IP \(bu 2 Macros must not be used as arguments to other macros. .IP \(bu 2 Macros must not be undefined. .IP \(bu 2 Macros must be defined at the top\-level, not inside any declaration or definition. .UNINDENT .sp Each cluster of macros meeting the above constraints is presumed to be a set of values suitable for replacement by an anonymous enum. From there, a developer can give the anonymous enum a name and continue refactoring to a scoped enum if desired. Comments on the same line as a macro definition or between subsequent macro definitions are preserved in the output. No formatting is assumed in the provided replacements, although clang\-tidy can optionally format all fixes. .sp \fBWARNING:\fP .INDENT 0.0 .INDENT 3.5 Initializing expressions are assumed to be valid initializers for an enum. C requires that enum values fit into an \fBint\fP, but this may not be the case for some accepted constant expressions. For instance \fB1 << 40\fP will not fit into an \fBint\fP when the size of an \fBint\fP is 32 bits. .UNINDENT .UNINDENT .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #define RED 0xFF0000 #define GREEN 0x00FF00 #define BLUE 0x0000FF #define TM_NONE (\-1) // No method selected. #define TM_ONE 1 // Use tailored method one. #define TM_TWO 2 // Use tailored method two. Method two // is preferable to method one. #define TM_THREE 3 // Use tailored method three. .ft P .fi .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C enum { RED = 0xFF0000, GREEN = 0x00FF00, BLUE = 0x0000FF }; enum { TM_NONE = (\-1), // No method selected. TM_ONE = 1, // Use tailored method one. TM_TWO = 2, // Use tailored method two. Method two // is preferable to method one. TM_THREE = 3 // Use tailored method three. }; .ft P .fi .UNINDENT .UNINDENT .SS modernize\-make\-shared .sp This check finds the creation of \fBstd::shared_ptr\fP objects by explicitly calling the constructor and a \fBnew\fP expression, and replaces it with a call to \fBstd::make_shared\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C auto my_ptr = std::shared_ptr(new MyPair(1, 2)); // becomes auto my_ptr = std::make_shared(1, 2); .ft P .fi .UNINDENT .UNINDENT .sp This check also finds calls to \fBstd::shared_ptr::reset()\fP with a \fBnew\fP expression, and replaces it with a call to \fBstd::make_shared\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C my_ptr.reset(new MyPair(1, 2)); // becomes my_ptr = std::make_shared(1, 2); .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B MakeSmartPtrFunction A string specifying the name of make\-shared\-ptr function. Default is \fIstd::make_shared\fP\&. .UNINDENT .INDENT 0.0 .TP .B MakeSmartPtrFunctionHeader A string specifying the corresponding header of make\-shared\-ptr function. Default is \fImemory\fP\&. .UNINDENT .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreMacros If set to \fItrue\fP, the check will not give warnings inside macros. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreDefaultInitialization If set to non\-zero, the check does not suggest edits that will transform default initialization into value initialization, as this can cause performance regressions. Default is \fI1\fP\&. .UNINDENT .SS modernize\-make\-unique .sp This check finds the creation of \fBstd::unique_ptr\fP objects by explicitly calling the constructor and a \fBnew\fP expression, and replaces it with a call to \fBstd::make_unique\fP, introduced in C++14. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C auto my_ptr = std::unique_ptr(new MyPair(1, 2)); // becomes auto my_ptr = std::make_unique(1, 2); .ft P .fi .UNINDENT .UNINDENT .sp This check also finds calls to \fBstd::unique_ptr::reset()\fP with a \fBnew\fP expression, and replaces it with a call to \fBstd::make_unique\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C my_ptr.reset(new MyPair(1, 2)); // becomes my_ptr = std::make_unique(1, 2); .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B MakeSmartPtrFunction A string specifying the name of make\-unique\-ptr function. Default is \fIstd::make_unique\fP\&. .UNINDENT .INDENT 0.0 .TP .B MakeSmartPtrFunctionHeader A string specifying the corresponding header of make\-unique\-ptr function. Default is \fI\fP\&. .UNINDENT .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreMacros If set to \fItrue\fP, the check will not give warnings inside macros. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreDefaultInitialization If set to non\-zero, the check does not suggest edits that will transform default initialization into value initialization, as this can cause performance regressions. Default is \fI1\fP\&. .UNINDENT .SS modernize\-pass\-by\-value .sp With move semantics added to the language and the standard library updated with move constructors added for many types it is now interesting to take an argument directly by value, instead of by const\-reference, and then copy. This check allows the compiler to take care of choosing the best way to construct the copy. .sp The transformation is usually beneficial when the calling code passes an \fIrvalue\fP and assumes the move construction is a cheap operation. This short example illustrates how the construction of the value happens: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(std::string s); std::string get_str(); void f(const std::string &str) { foo(str); // lvalue \-> copy construction foo(get_str()); // prvalue \-> move construction } .ft P .fi .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 Currently, only constructors are transformed to make use of pass\-by\-value. Contributions that handle other situations are welcome! .UNINDENT .UNINDENT .SS Pass\-by\-value in constructors .sp Replaces the uses of const\-references constructor parameters that are copied into class fields. The parameter is then moved with \fIstd::move()\fP\&. .sp Since \fBstd::move()\fP is a library function declared in \fI\fP it may be necessary to add this include. The check will add the include directive when necessary. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include class Foo { public: \- Foo(const std::string &Copied, const std::string &ReadOnly) \- : Copied(Copied), ReadOnly(ReadOnly) + Foo(std::string Copied, const std::string &ReadOnly) + : Copied(std::move(Copied)), ReadOnly(ReadOnly) {} private: std::string Copied; const std::string &ReadOnly; }; std::string get_cwd(); void f(const std::string &Path) { // The parameter corresponding to \(aqget_cwd()\(aq is move\-constructed. By // using pass\-by\-value in the Foo constructor we managed to avoid a // copy\-construction. Foo foo(get_cwd(), Path); } .ft P .fi .UNINDENT .UNINDENT .sp If the parameter is used more than once no transformation is performed since moved objects have an undefined state. It means the following code will be left untouched: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include void pass(const std::string &S); struct Foo { Foo(const std::string &S) : Str(S) { pass(S); } std::string Str; }; .ft P .fi .UNINDENT .UNINDENT .SS Known limitations .sp A situation where the generated code can be wrong is when the object referenced is modified before the assignment in the init\-list through a \(dqhidden\(dq reference. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string s(\(dqfoo\(dq); struct Base { Base() { s = \(dqbar\(dq; } }; struct Derived : Base { \- Derived(const std::string &S) : Field(S) + Derived(std::string S) : Field(std::move(S)) { } std::string Field; }; void f() { \- Derived d(s); // d.Field holds \(dqbar\(dq + Derived d(s); // d.Field holds \(dqfoo\(dq } .ft P .fi .UNINDENT .UNINDENT .SS Note about delayed template parsing .sp When delayed template parsing is enabled, constructors part of templated contexts; templated constructors, constructors in class templates, constructors of inner classes of template classes, etc., are not transformed. Delayed template parsing is enabled by default on Windows as a Microsoft extension: \fI\%Clang Compiler User\(aqs Manual \- Microsoft extensions\fP\&. .sp Delayed template parsing can be enabled using the \fI\-fdelayed\-template\-parsing\fP flag and disabled using \fI\-fno\-delayed\-template\-parsing\fP\&. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C template class C { std::string S; public: = // using \-fdelayed\-template\-parsing (default on Windows) = C(const std::string &S) : S(S) {} + // using \-fno\-delayed\-template\-parsing (default on non\-Windows systems) + C(std::string S) : S(std::move(S)) {} }; .ft P .fi .UNINDENT .UNINDENT .sp \fBSEE ALSO:\fP .INDENT 0.0 .INDENT 3.5 For more information about the pass\-by\-value idiom, read: \fI\%Want Speed? Pass by Value\fP\&. .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B ValuesOnly When \fItrue\fP, the check only warns about copied parameters that are already passed by value. Default is \fIfalse\fP\&. .UNINDENT .SS modernize\-raw\-string\-literal .sp This check selectively replaces string literals containing escaped characters with raw string literals. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const char *const Quotes{\(dqembedded \e\(dqquotes\e\(dq\(dq}; const char *const Paragraph{\(dqLine one.\enLine two.\enLine three.\en\(dq}; const char *const SingleLine{\(dqSingle line.\en\(dq}; const char *const TrailingSpace{\(dqLook here \-> \en\(dq}; const char *const Tab{\(dqOne\etTwo\en\(dq}; const char *const Bell{\(dqHello!\ea And welcome!\(dq}; const char *const Path{\(dqC:\e\eProgram Files\e\eVendor\e\eApplication.exe\(dq}; const char *const RegEx{\(dq\e\ew\e\e([a\-z]\e\e)\(dq}; .ft P .fi .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const char *const Quotes{R\(dq(embedded \(dqquotes\(dq)\(dq}; const char *const Paragraph{\(dqLine one.\enLine two.\enLine three.\en\(dq}; const char *const SingleLine{\(dqSingle line.\en\(dq}; const char *const TrailingSpace{\(dqLook here \-> \en\(dq}; const char *const Tab{\(dqOne\etTwo\en\(dq}; const char *const Bell{\(dqHello!\ea And welcome!\(dq}; const char *const Path{R\(dq(C:\eProgram Files\eVendor\eApplication.exe)\(dq}; const char *const RegEx{R\(dq(\ew\e([a\-z]\e))\(dq}; .ft P .fi .UNINDENT .UNINDENT .sp The presence of any of the following escapes can cause the string to be converted to a raw string literal: \fB\e\e\fP, \fB\e\(aq\fP, \fB\e\(dq\fP, \fB\e?\fP, and octal or hexadecimal escapes for printable ASCII characters. .sp A string literal containing only escaped newlines is a common way of writing lines of text output. Introducing physical newlines with raw string literals in this case is likely to impede readability. These string literals are left unchanged. .sp An escaped horizontal tab, form feed, or vertical tab prevents the string literal from being converted. The presence of a horizontal tab, form feed or vertical tab in source code is not visually obvious. .INDENT 0.0 .TP .B DelimiterStem Custom delimiter to escape characters in raw string literals. It is used in the following construction: \fBR\(dqstem_delimiter(contents)stem_delimiter\(dq\fP\&. The default value is \fIlit\fP\&. .UNINDENT .INDENT 0.0 .TP .B ReplaceShorterLiterals Controls replacing shorter non\-raw string literals with longer raw string literals. Setting this option to \fItrue\fP enables the replacement. The default value is \fIfalse\fP (shorter literals are not replaced). .UNINDENT .SS modernize\-redundant\-void\-arg .sp Find and remove redundant \fBvoid\fP argument lists. .INDENT 0.0 .TP .B Examples: .TS center; |l|l|. _ T{ Initial code T} T{ Code with applied fixes T} _ T{ \fBint f(void);\fP T} T{ \fBint f();\fP T} _ T{ \fBint (*f(void))(void);\fP T} T{ \fBint (*f())();\fP T} _ T{ \fBtypedef int (*f_t(void))(void);\fP T} T{ \fBtypedef int (*f_t())();\fP T} _ T{ \fBvoid (C::*p)(void);\fP T} T{ \fBvoid (C::*p)();\fP T} _ T{ \fBC::C(void) {}\fP T} T{ \fBC::C() {}\fP T} _ T{ \fBC::~C(void) {}\fP T} T{ \fBC::~C() {}\fP T} _ .TE .UNINDENT .SS modernize\-replace\-auto\-ptr .sp This check replaces the uses of the deprecated class \fBstd::auto_ptr\fP by \fBstd::unique_ptr\fP (introduced in C++11). The transfer of ownership, done by the copy\-constructor and the assignment operator, is changed to match \fBstd::unique_ptr\fP usage by using explicit calls to \fBstd::move()\fP\&. .sp Migration example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-void take_ownership_fn(std::auto_ptr int_ptr); +void take_ownership_fn(std::unique_ptr int_ptr); void f(int x) { \- std::auto_ptr a(new int(x)); \- std::auto_ptr b; + std::unique_ptr a(new int(x)); + std::unique_ptr b; \- b = a; \- take_ownership_fn(b); + b = std::move(a); + take_ownership_fn(std::move(b)); } .ft P .fi .UNINDENT .UNINDENT .sp Since \fBstd::move()\fP is a library function declared in \fB\fP it may be necessary to add this include. The check will add the include directive when necessary. .SS Known Limitations .INDENT 0.0 .IP \(bu 2 If headers modification is not activated or if a header is not allowed to be changed this check will produce broken code (compilation error), where the headers\(aq code will stay unchanged while the code using them will be changed. .IP \(bu 2 Client code that declares a reference to an \fBstd::auto_ptr\fP coming from code that can\(aqt be migrated (such as a header coming from a 3\s-2\urd\d\s0 party library) will produce a compilation error after migration. This is because the type of the reference will be changed to \fBstd::unique_ptr\fP but the type returned by the library won\(aqt change, binding a reference to \fBstd::unique_ptr\fP from an \fBstd::auto_ptr\fP\&. This pattern doesn\(aqt make much sense and usually \fBstd::auto_ptr\fP are stored by value (otherwise what is the point in using them instead of a reference or a pointer?). .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // <3rd\-party header...> std::auto_ptr get_value(); const std::auto_ptr & get_ref(); // \-std::auto_ptr a(get_value()); +std::unique_ptr a(get_value()); // ok, unique_ptr constructed from auto_ptr \-const std::auto_ptr & p = get_ptr(); +const std::unique_ptr & p = get_ptr(); // won\(aqt compile .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 Non\-instantiated templates aren\(aqt modified. .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C template void f() { std::auto_ptr p; } // only \(aqf()\(aq (or similar) will trigger the replacement. .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .SS modernize\-replace\-disallow\-copy\-and\-assign\-macro .sp Finds macro expansions of \fBDISALLOW_COPY_AND_ASSIGN(Type)\fP and replaces them with a deleted copy constructor and a deleted assignment operator. .sp Before the \fBdelete\fP keyword was introduced in C++11 it was common practice to declare a copy constructor and an assignment operator as private members. This effectively makes them unusable to the public API of a class. .sp With the advent of the \fBdelete\fP keyword in C++11 we can abandon the \fBprivate\fP access of the copy constructor and the assignment operator and delete the methods entirely. .sp When running this check on a code like this: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { private: DISALLOW_COPY_AND_ASSIGN(Foo); }; .ft P .fi .UNINDENT .UNINDENT .sp It will be transformed to this: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { private: Foo(const Foo &) = delete; const Foo &operator=(const Foo &) = delete; }; .ft P .fi .UNINDENT .UNINDENT .SS Known Limitations .INDENT 0.0 .IP \(bu 2 Notice that the migration example above leaves the \fBprivate\fP access specification untouched. You might want to run the check \fI\%modernize\-use\-equals\-delete\fP to get warnings for deleted functions in private sections. .UNINDENT .SS Options .INDENT 0.0 .TP .B MacroName A string specifying the macro name whose expansion will be replaced. Default is \fIDISALLOW_COPY_AND_ASSIGN\fP\&. .UNINDENT .sp See: \fI\%https://en.cppreference.com/w/cpp/language/function#Deleted_functions\fP .SS modernize\-replace\-random\-shuffle .sp This check will find occurrences of \fBstd::random_shuffle\fP and replace it with \fBstd::shuffle\fP\&. In C++17 \fBstd::random_shuffle\fP will no longer be available and thus we need to replace it. .sp Below are two examples of what kind of occurrences will be found and two examples of what it will be replaced with. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector v; // First example std::random_shuffle(vec.begin(), vec.end()); // Second example std::random_shuffle(vec.begin(), vec.end(), randomFunc); .ft P .fi .UNINDENT .UNINDENT .sp Both of these examples will be replaced with: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()())); .ft P .fi .UNINDENT .UNINDENT .sp The second example will also receive a warning that \fBrandomFunc\fP is no longer supported in the same way as before so if the user wants the same functionality, the user will need to change the implementation of the \fBrandomFunc\fP\&. .sp One thing to be aware of here is that \fBstd::random_device\fP is quite expensive to initialize. So if you are using the code in a performance critical place, you probably want to initialize it elsewhere. Another thing is that the seeding quality of the suggested fix is quite poor: \fBstd::mt19937\fP has an internal state of 624 32\-bit integers, but is only seeded with a single integer. So if you require higher quality randomness, you should consider seeding better, for example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::shuffle(v.begin(), v.end(), []() { std::mt19937::result_type seeds[std::mt19937::state_size]; std::random_device device; std::uniform_int_distribution dist; std::generate(std::begin(seeds), std::end(seeds), [&] { return dist(device); }); std::seed_seq seq(std::begin(seeds), std::end(seeds)); return std::mt19937(seq); }()); .ft P .fi .UNINDENT .UNINDENT .SS modernize\-return\-braced\-init\-list .sp Replaces explicit calls to the constructor in a return with a braced initializer list. This way the return type is not needlessly duplicated in the function definition and the return statement. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C Foo bar() { Baz baz; return Foo(baz); } // transforms to: Foo bar() { Baz baz; return {baz}; } .ft P .fi .UNINDENT .UNINDENT .SS modernize\-shrink\-to\-fit .sp Replace copy and swap tricks on shrinkable containers with the \fBshrink_to_fit()\fP method call. .sp The \fBshrink_to_fit()\fP method is more readable and more effective than the copy and swap trick to reduce the capacity of a shrinkable container. Note that, the \fBshrink_to_fit()\fP method is only available in C++11 and up. .SS modernize\-type\-traits .sp Converts standard library type traits of the form \fBtraits<...>::type\fP and \fBtraits<...>::value\fP into \fBtraits_t<...>\fP and \fBtraits_v<...>\fP respectively. .sp For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::is_integral::value std::is_same::value typename std::add_const::type std::make_signed::type .ft P .fi .UNINDENT .UNINDENT .sp Would be converted into: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::is_integral_v std::is_same_v std::add_const_t std::make_signed_t .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreMacros If \fItrue\fP don\(aqt diagnose traits defined in macros. .sp Note: Fixes will never be emitted for code inside of macros. .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C #define IS_SIGNED(T) std::is_signed::value .ft P .fi .UNINDENT .UNINDENT .sp Defaults to \fIfalse\fP\&. .UNINDENT .SS modernize\-unary\-static\-assert .sp The check diagnoses any \fBstatic_assert\fP declaration with an empty string literal and provides a fix\-it to replace the declaration with a single\-argument \fBstatic_assert\fP declaration. .sp The check is only applicable for C++17 and later code. .sp The following code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f_textless(int a) { static_assert(sizeof(a) <= 10, \(dq\(dq); } .ft P .fi .UNINDENT .UNINDENT .sp is replaced by: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f_textless(int a) { static_assert(sizeof(a) <= 10); } .ft P .fi .UNINDENT .UNINDENT .SS modernize\-use\-auto .sp This check is responsible for using the \fBauto\fP type specifier for variable declarations to \fIimprove code readability and maintainability\fP\&. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector::iterator I = my_container.begin(); // transforms to: auto I = my_container.begin(); .ft P .fi .UNINDENT .UNINDENT .sp The \fBauto\fP type specifier will only be introduced in situations where the variable type matches the type of the initializer expression. In other words \fBauto\fP should deduce the same type that was originally spelled in the source. However, not every situation should be transformed: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int val = 42; InfoStruct &I = SomeObject.getInfo(); // Should not become: auto val = 42; auto &I = SomeObject.getInfo(); .ft P .fi .UNINDENT .UNINDENT .sp In this example using \fBauto\fP for builtins doesn\(aqt improve readability. In other situations it makes the code less self\-documenting impairing readability and maintainability. As a result, \fBauto\fP is used only introduced in specific situations described below. .SS Iterators .sp Iterator type specifiers tend to be long and used frequently, especially in loop constructs. Since the functions generating iterators have a common format, the type specifier can be replaced without obscuring the meaning of code while improving readability and maintainability. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C for (std::vector::iterator I = my_container.begin(), E = my_container.end(); I != E; ++I) { } // becomes for (auto I = my_container.begin(), E = my_container.end(); I != E; ++I) { } .ft P .fi .UNINDENT .UNINDENT .sp The check will only replace iterator type\-specifiers when all of the following conditions are satisfied: .INDENT 0.0 .IP \(bu 2 The iterator is for one of the standard containers in \fBstd\fP namespace: .INDENT 2.0 .IP \(bu 2 \fBarray\fP .IP \(bu 2 \fBdeque\fP .IP \(bu 2 \fBforward_list\fP .IP \(bu 2 \fBlist\fP .IP \(bu 2 \fBvector\fP .IP \(bu 2 \fBmap\fP .IP \(bu 2 \fBmultimap\fP .IP \(bu 2 \fBset\fP .IP \(bu 2 \fBmultiset\fP .IP \(bu 2 \fBunordered_map\fP .IP \(bu 2 \fBunordered_multimap\fP .IP \(bu 2 \fBunordered_set\fP .IP \(bu 2 \fBunordered_multiset\fP .IP \(bu 2 \fBqueue\fP .IP \(bu 2 \fBpriority_queue\fP .IP \(bu 2 \fBstack\fP .UNINDENT .IP \(bu 2 The iterator is one of the possible iterator types for standard containers: .INDENT 2.0 .IP \(bu 2 \fBiterator\fP .IP \(bu 2 \fBreverse_iterator\fP .IP \(bu 2 \fBconst_iterator\fP .IP \(bu 2 \fBconst_reverse_iterator\fP .UNINDENT .IP \(bu 2 In addition to using iterator types directly, typedefs or other ways of referring to those types are also allowed. However, implementation\-specific types for which a type like \fBstd::vector::iterator\fP is itself a typedef will not be transformed. Consider the following examples: .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // The following direct uses of iterator types will be transformed. std::vector::iterator I = MyVec.begin(); { using namespace std; list::iterator I = MyList.begin(); } // The type specifier for J would transform to auto since it\(aqs a typedef // to a standard iterator type. typedef std::map::const_iterator map_iterator; map_iterator J = MyMap.begin(); // The following implementation\-specific iterator type for which // std::vector::iterator could be a typedef would not be transformed. __gnu_cxx::__normal_iterator K = MyVec.begin(); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 The initializer for the variable being declared is not a braced initializer list. Otherwise, use of \fBauto\fP would cause the type of the variable to be deduced as \fBstd::initializer_list\fP\&. .UNINDENT .SS New expressions .sp Frequently, when a pointer is declared and initialized with \fBnew\fP, the pointee type is written twice: in the declaration type and in the \fBnew\fP expression. In this case, the declaration type can be replaced with \fBauto\fP improving readability and maintainability. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C TypeName *my_pointer = new TypeName(my_param); // becomes auto *my_pointer = new TypeName(my_param); .ft P .fi .UNINDENT .UNINDENT .sp The check will also replace the declaration type in multiple declarations, if the following conditions are satisfied: .INDENT 0.0 .IP \(bu 2 All declared variables have the same type (i.e. all of them are pointers to the same type). .IP \(bu 2 All declared variables are initialized with a \fBnew\fP expression. .IP \(bu 2 The types of all the new expressions are the same than the pointee of the declaration type. .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName; // becomes auto *my_first_pointer = new TypeName, *my_second_pointer = new TypeName; .ft P .fi .UNINDENT .UNINDENT .SS Cast expressions .sp Frequently, when a variable is declared and initialized with a cast, the variable type is written twice: in the declaration type and in the cast expression. In this case, the declaration type can be replaced with \fBauto\fP improving readability and maintainability. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C TypeName *my_pointer = static_cast(my_param); // becomes auto *my_pointer = static_cast(my_param); .ft P .fi .UNINDENT .UNINDENT .sp The check handles \fBstatic_cast\fP, \fBdynamic_cast\fP, \fBconst_cast\fP, \fBreinterpret_cast\fP, functional casts, C\-style casts and function templates that behave as casts, such as \fBllvm::dyn_cast\fP, \fBboost::lexical_cast\fP and \fBgsl::narrow_cast\fP\&. Calls to function templates are considered to behave as casts if the first template argument is explicit and is a type, and the function returns that type, or a pointer or reference to it. .SS Known Limitations .INDENT 0.0 .IP \(bu 2 If the initializer is an explicit conversion constructor, the check will not replace the type specifier even though it would be safe to do so. .IP \(bu 2 User\-defined iterators are not handled at this time. .UNINDENT .SS Options .INDENT 0.0 .TP .B MinTypeNameLength If the option is set to non\-zero (default \fI5\fP), the check will ignore type names having a length less than the option value. The option affects expressions only, not iterators. Spaces between multi\-lexeme type names (\fBlong int\fP) are considered as one. If the \fI\%RemoveStars\fP option (see below) is set to \fItrue\fP, then \fB*s\fP in the type are also counted as a part of the type name. .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // MinTypeNameLength = 0, RemoveStars=0 int a = static_cast(foo()); // \-\-\-> auto a = ... // length(bool *) = 4 bool *b = new bool; // \-\-\-> auto *b = ... unsigned c = static_cast(foo()); // \-\-\-> auto c = ... // MinTypeNameLength = 5, RemoveStars=0 int a = static_cast(foo()); // \-\-\-> int a = ... bool b = static_cast(foo()); // \-\-\-> bool b = ... bool *pb = static_cast(foo()); // \-\-\-> bool *pb = ... unsigned c = static_cast(foo()); // \-\-\-> auto c = ... // length(long int) = 8 long int d = static_cast(foo()); // \-\-\-> auto d = ... // MinTypeNameLength = 5, RemoveStars=1 int a = static_cast(foo()); // \-\-\-> int a = ... // length(int * * ) = 5 int **pa = static_cast(foo()); // \-\-\-> auto pa = ... bool b = static_cast(foo()); // \-\-\-> bool b = ... bool *pb = static_cast(foo()); // \-\-\-> auto pb = ... unsigned c = static_cast(foo()); // \-\-\-> auto c = ... long int d = static_cast(foo()); // \-\-\-> auto d = ... .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B RemoveStars If the option is set to \fItrue\fP (default is \fIfalse\fP), the check will remove stars from the non\-typedef pointer types when replacing type names with \fBauto\fP\&. Otherwise, the check will leave stars. For example: .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName; // RemoveStars = 0 auto *my_first_pointer = new TypeName, *my_second_pointer = new TypeName; // RemoveStars = 1 auto my_first_pointer = new TypeName, my_second_pointer = new TypeName; .ft P .fi .UNINDENT .UNINDENT .SS modernize\-use\-bool\-literals .sp Finds integer literals which are cast to \fBbool\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bool p = 1; bool f = static_cast(1); std::ios_base::sync_with_stdio(0); bool x = p ? 1 : 0; // transforms to bool p = true; bool f = true; std::ios_base::sync_with_stdio(false); bool x = p ? true : false; .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreMacros If set to \fItrue\fP, the check will not give warnings inside macros. Default is \fItrue\fP\&. .UNINDENT .SS modernize\-use\-default .sp This check has been renamed to \fI\%modernize\-use\-equals\-default\fP\&. .SS modernize\-use\-default\-member\-init .sp This check converts constructors\(aq member initializers into the new default member initializers in C++11. Other member initializers that match the default member initializer are removed. This can reduce repeated code or allow use of \(aq= default\(aq. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct A { A() : i(5), j(10.0) {} A(int i) : i(i), j(10.0) {} int i; double j; }; // becomes struct A { A() {} A(int i) : i(i) {} int i{5}; double j{10.0}; }; .ft P .fi .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 Only converts member initializers for built\-in types, enums, and pointers. The \fIreadability\-redundant\-member\-init\fP check will remove redundant member initializers for classes. .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B UseAssignment If this option is set to \fItrue\fP (default is \fIfalse\fP), the check will initialize members with an assignment. For example: .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct A { A() {} A(int i) : i(i) {} int i = 5; double j = 10.0; }; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B IgnoreMacros If this option is set to \fItrue\fP (default is \fItrue\fP), the check will not warn about members declared inside macros. .UNINDENT .SS modernize\-use\-emplace .sp The check flags insertions to an STL\-style container done by calling the \fBpush_back\fP, \fBpush\fP, or \fBpush_front\fP methods with an explicitly\-constructed temporary of the container element type. In this case, the corresponding \fBemplace\fP equivalent methods result in less verbose and potentially more efficient code. Right now the check doesn\(aqt support \fBinsert\fP\&. It also doesn\(aqt support \fBinsert\fP functions for associative containers because replacing \fBinsert\fP with \fBemplace\fP may result in \fI\%speed regression\fP, but it might get support with some addition flag in the future. .sp The \fI\%ContainersWithPushBack\fP, \fI\%ContainersWithPush\fP, and \fI\%ContainersWithPushFront\fP options are used to specify the container types that support the \fBpush_back\fP, \fBpush\fP, and \fBpush_front\fP operations respectively. The default values for these options are as follows: .INDENT 0.0 .IP \(bu 2 \fI\%ContainersWithPushBack\fP: \fBstd::vector\fP, \fBstd::deque\fP, and \fBstd::list\fP\&. .IP \(bu 2 \fI\%ContainersWithPush\fP: \fBstd::stack\fP, \fBstd::queue\fP, and \fBstd::priority_queue\fP\&. .IP \(bu 2 \fI\%ContainersWithPushFront\fP: \fBstd::forward_list\fP, \fBstd::list\fP, and \fBstd::deque\fP\&. .UNINDENT .sp This check also reports when an \fBemplace\fP\-like method is improperly used, for example using \fBemplace_back\fP while also calling a constructor. This creates a temporary that requires at best a move and at worst a copy. Almost all \fBemplace\fP\-like functions in the STL are covered by this, with \fBtry_emplace\fP on \fBstd::map\fP and \fBstd::unordered_map\fP being the exception as it behaves slightly differently than all the others. More containers can be added with the \fI\%EmplacyFunctions\fP option, so long as the container defines a \fBvalue_type\fP type, and the \fBemplace\fP\-like functions construct a \fBvalue_type\fP object. .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector v; v.push_back(MyClass(21, 37)); v.emplace_back(MyClass(21, 37)); std::vector> w; w.push_back(std::pair(21, 37)); w.push_back(std::make_pair(21L, 37L)); w.emplace_back(std::make_pair(21L, 37L)); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector v; v.emplace_back(21, 37); v.emplace_back(21, 37); std::vector> w; w.emplace_back(21, 37); w.emplace_back(21L, 37L); w.emplace_back(21L, 37L); .ft P .fi .UNINDENT .UNINDENT .sp By default, the check is able to remove unnecessary \fBstd::make_pair\fP and \fBstd::make_tuple\fP calls from \fBpush_back\fP calls on containers of \fBstd::pair\fP and \fBstd::tuple\fP\&. Custom tuple\-like types can be modified by the \fI\%TupleTypes\fP option; custom make functions can be modified by the \fI\%TupleMakeFunctions\fP option. .sp The other situation is when we pass arguments that will be converted to a type inside a container. .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector > v; v.push_back(\(dqabc\(dq); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector > v; v.emplace_back(\(dqabc\(dq); .ft P .fi .UNINDENT .UNINDENT .sp In some cases the transformation would be valid, but the code wouldn\(aqt be exception safe. In this case the calls of \fBpush_back\fP won\(aqt be replaced. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector> v; v.push_back(std::unique_ptr(new int(0))); auto *ptr = new int(1); v.push_back(std::unique_ptr(ptr)); .ft P .fi .UNINDENT .UNINDENT .sp This is because replacing it with \fBemplace_back\fP could cause a leak of this pointer if \fBemplace_back\fP would throw exception before emplacement (e.g. not enough memory to add a new element). .sp For more info read item 42 \- \(dqConsider emplacement instead of insertion.\(dq of Scott Meyers \(dqEffective Modern C++\(dq. .sp The default smart pointers that are considered are \fBstd::unique_ptr\fP, \fBstd::shared_ptr\fP, \fBstd::auto_ptr\fP\&. To specify other smart pointers or other classes use the \fI\%SmartPointers\fP option. .sp Check also doesn\(aqt fire if any argument of the constructor call would be: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 a bit\-field (bit\-fields can\(aqt bind to rvalue/universal reference) .IP \(bu 2 a \fBnew\fP expression (to avoid leak) .IP \(bu 2 if the argument would be converted via derived\-to\-base cast. .UNINDENT .UNINDENT .UNINDENT .sp This check requires C++11 or higher to run. .SS Options .INDENT 0.0 .TP .B ContainersWithPushBack Semicolon\-separated list of class names of custom containers that support \fBpush_back\fP\&. .UNINDENT .INDENT 0.0 .TP .B ContainersWithPush Semicolon\-separated list of class names of custom containers that support \fBpush\fP\&. .UNINDENT .INDENT 0.0 .TP .B ContainersWithPushFront Semicolon\-separated list of class names of custom containers that support \fBpush_front\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreImplicitConstructors When \fItrue\fP, the check will ignore implicitly constructed arguments of \fBpush_back\fP, e.g. .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C std::vector v; v.push_back(\(dqa\(dq); // Ignored when IgnoreImplicitConstructors is \(gatrue\(ga. .ft P .fi .UNINDENT .UNINDENT .sp Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B SmartPointers Semicolon\-separated list of class names of custom smart pointers. .UNINDENT .INDENT 0.0 .TP .B TupleTypes Semicolon\-separated list of \fBstd::tuple\fP\-like class names. .UNINDENT .INDENT 0.0 .TP .B TupleMakeFunctions Semicolon\-separated list of \fBstd::make_tuple\fP\-like function names. Those function calls will be removed from \fBpush_back\fP calls and turned into \fBemplace_back\fP\&. .UNINDENT .INDENT 0.0 .TP .B EmplacyFunctions Semicolon\-separated list of containers without their template parameters and some \fBemplace\fP\-like method of the container. Example: \fBvector::emplace_back\fP\&. Those methods will be checked for improper use and the check will report when a temporary is unnecessarily created. .UNINDENT .SS Example .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector> x; x.push_back(MakeMyTuple(1, false, \(aqx\(aq)); x.emplace_back(MakeMyTuple(1, false, \(aqx\(aq)); .ft P .fi .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector> x; x.emplace_back(1, false, \(aqx\(aq); x.emplace_back(1, false, \(aqx\(aq); .ft P .fi .UNINDENT .UNINDENT .sp when \fI\%TupleTypes\fP is set to \fBMyTuple\fP, \fI\%TupleMakeFunctions\fP is set to \fBMakeMyTuple\fP, and \fI\%EmplacyFunctions\fP is set to \fBvector::emplace_back\fP\&. .SS modernize\-use\-equals\-default .sp This check replaces default bodies of special member functions with \fB= default;\fP\&. The explicitly defaulted function declarations enable more opportunities in optimization, because the compiler might treat explicitly defaulted functions as trivial. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct A { A() {} ~A(); }; A::~A() {} // becomes struct A { A() = default; ~A(); }; A::~A() = default; .ft P .fi .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 Move\-constructor and move\-assignment operator are not supported yet. .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreMacros If set to \fItrue\fP, the check will not give warnings inside macros and will ignore special members with bodies contain macros or preprocessor directives. Default is \fItrue\fP\&. .UNINDENT .SS modernize\-use\-equals\-delete .sp This check marks unimplemented private special member functions with \fB= delete\fP\&. To avoid false\-positives, this check only applies in a translation unit that has all other member functions implemented. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct A { private: A(const A&); A& operator=(const A&); }; // becomes struct A { private: A(const A&) = delete; A& operator=(const A&) = delete; }; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B IgnoreMacros If this option is set to \fItrue\fP (default is \fItrue\fP), the check will not warn about functions declared inside macros. .UNINDENT .SS modernize\-use\-nodiscard .sp Adds \fB[[nodiscard]]\fP attributes (introduced in C++17) to member functions in order to highlight at compile time which return values should not be ignored. .sp Member functions need to satisfy the following conditions to be considered by this check: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 no \fB[[nodiscard]]\fP, \fB[[noreturn]]\fP, \fB__attribute__((warn_unused_result))\fP, \fB[[clang::warn_unused_result]]\fP nor \fB[[gcc::warn_unused_result]]\fP attribute, .IP \(bu 2 non\-void return type, .IP \(bu 2 non\-template return types, .IP \(bu 2 const member function, .IP \(bu 2 non\-variadic functions, .IP \(bu 2 no non\-const reference parameters, .IP \(bu 2 no pointer parameters, .IP \(bu 2 no template parameters, .IP \(bu 2 no template function parameters, .IP \(bu 2 not be a member of a class with mutable member variables, .IP \(bu 2 no Lambdas, .IP \(bu 2 no conversion functions. .UNINDENT .UNINDENT .UNINDENT .sp Such functions have no means of altering any state or passing values other than via the return type. Unless the member functions are altering state via some external call (e.g. I/O). .SS Example .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bool empty() const; bool empty(int i) const; .ft P .fi .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C [[nodiscard]] bool empty() const; [[nodiscard]] bool empty(int i) const; .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B ReplacementString Specifies a macro to use instead of \fB[[nodiscard]]\fP\&. This is useful when maintaining source code that needs to compile with a pre\-C++17 compiler. .UNINDENT .SS Example .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C bool empty() const; bool empty(int i) const; .ft P .fi .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C NO_DISCARD bool empty() const; NO_DISCARD bool empty(int i) const; .ft P .fi .UNINDENT .UNINDENT .sp if the \fI\%ReplacementString\fP option is set to \fINO_DISCARD\fP\&. .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 If the \fI\%ReplacementString\fP is not a C++ attribute, but instead a macro, then that macro must be defined in scope or the fix\-it will not be applied. .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 For alternative \fB__attribute__\fP syntax options to mark functions as \fB[[nodiscard]]\fP in non\-c++17 source code. See \fI\%https://clang.llvm.org/docs/AttributeReference.html#nodiscard\-warn\-unused\-result\fP .UNINDENT .UNINDENT .SS modernize\-use\-noexcept .sp This check replaces deprecated dynamic exception specifications with the appropriate noexcept specification (introduced in C++11). By default this check will replace \fBthrow()\fP with \fBnoexcept\fP, and \fBthrow([,...])\fP or \fBthrow(...)\fP with \fBnoexcept(false)\fP\&. .SS Example .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo() throw(); void bar() throw(int) {} .ft P .fi .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo() noexcept; void bar() noexcept(false) {} .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B ReplacementString Users can use \fI\%ReplacementString\fP to specify a macro to use instead of \fBnoexcept\fP\&. This is useful when maintaining source code that uses custom exception specification marking other than \fBnoexcept\fP\&. Fix\-it hints will only be generated for non\-throwing specifications. .UNINDENT .SS Example .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void bar() throw(int); void foo() throw(); .ft P .fi .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void bar() throw(int); // No fix\-it generated. void foo() NOEXCEPT; .ft P .fi .UNINDENT .UNINDENT .sp if the \fI\%ReplacementString\fP option is set to \fINOEXCEPT\fP\&. .INDENT 0.0 .TP .B UseNoexceptFalse .UNINDENT .sp Enabled by default, disabling will generate fix\-it hints that remove throwing dynamic exception specs, e.g., \fBthrow()\fP, completely without providing a replacement text, except for destructors and delete operators that are \fBnoexcept(true)\fP by default. .SS Example .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo() throw(int) {} struct bar { void foobar() throw(int); void operator delete(void *ptr) throw(int); void operator delete[](void *ptr) throw(int); ~bar() throw(int); } .ft P .fi .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo() {} struct bar { void foobar(); void operator delete(void *ptr) noexcept(false); void operator delete[](void *ptr) noexcept(false); ~bar() noexcept(false); } .ft P .fi .UNINDENT .UNINDENT .sp if the \fI\%UseNoexceptFalse\fP option is set to \fIfalse\fP\&. .SS modernize\-use\-nullptr .sp The check converts the usage of null pointer constants (e.g. \fBNULL\fP, \fB0\fP) to use the new C++11 \fBnullptr\fP keyword. .SS Example .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void assignment() { char *a = NULL; char *b = 0; char c = 0; } int *ret_ptr() { return 0; } .ft P .fi .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void assignment() { char *a = nullptr; char *b = nullptr; char c = 0; } int *ret_ptr() { return nullptr; } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B NullMacros Comma\-separated list of macro names that will be transformed along with \fBNULL\fP\&. By default this check will only replace the \fBNULL\fP macro and will skip any similar user\-defined macros. .UNINDENT .SS Example .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #define MY_NULL (void*)0 void assignment() { void *p = MY_NULL; } .ft P .fi .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #define MY_NULL NULL void assignment() { int *p = nullptr; } .ft P .fi .UNINDENT .UNINDENT .sp if the \fI\%NullMacros\fP option is set to \fBMY_NULL\fP\&. .SS modernize\-use\-override .sp Adds \fBoverride\fP (introduced in C++11) to overridden virtual functions and removes \fBvirtual\fP from those functions as it is not required. .sp \fBvirtual\fP on non base class implementations was used to help indicate to the user that a function was virtual. C++ compilers did not use the presence of this to signify an overridden function. .sp In C++ 11 \fBoverride\fP and \fBfinal\fP keywords were introduced to allow overridden functions to be marked appropriately. Their presence allows compilers to verify that an overridden function correctly overrides a base class implementation. .sp This can be useful as compilers can generate a compile time error when: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 The base class implementation function signature changes. .IP \(bu 2 The user has not created the override with the correct signature. .UNINDENT .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreDestructors If set to \fItrue\fP, this check will not diagnose destructors. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreTemplateInstantiations If set to \fItrue\fP, instructs this check to ignore virtual function overrides that are part of template instantiations. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B AllowOverrideAndFinal If set to \fItrue\fP, this check will not diagnose \fBoverride\fP as redundant with \fBfinal\fP\&. This is useful when code will be compiled by a compiler with warning/error checking flags requiring \fBoverride\fP explicitly on overridden members, such as \fBgcc \-Wsuggest\-override\fP/\fBgcc \-Werror=suggest\-override\fP\&. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B OverrideSpelling Specifies a macro to use instead of \fBoverride\fP\&. This is useful when maintaining source code that also needs to compile with a pre\-C++11 compiler. .UNINDENT .INDENT 0.0 .TP .B FinalSpelling Specifies a macro to use instead of \fBfinal\fP\&. This is useful when maintaining source code that also needs to compile with a pre\-C++11 compiler. .UNINDENT .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 For more information on the use of \fBoverride\fP see \fI\%https://en.cppreference.com/w/cpp/language/override\fP .UNINDENT .UNINDENT .SS modernize\-use\-std\-print .sp Converts calls to \fBprintf\fP, \fBfprintf\fP, \fBabsl::PrintF\fP and \fBabsl::FPrintf\fP to equivalent calls to C++23\(aqs \fBstd::print\fP or \fBstd::println\fP as appropriate, modifying the format string appropriately. The replaced and replacement functions can be customised by configuration options. Each argument that is the result of a call to \fBstd::string::c_str()\fP and \fBstd::string::data()\fP will have that now\-unnecessary call removed in a similar manner to the \fIreadability\-redundant\-string\-cstr\fP check. .sp In other words, it turns lines like: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C fprintf(stderr, \(dqThe %s is %3d\en\(dq, description.c_str(), value); .ft P .fi .UNINDENT .UNINDENT .sp into: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::println(stderr, \(dqThe {} is {:3}\(dq, description, value); .ft P .fi .UNINDENT .UNINDENT .sp If the \fIReplacementPrintFunction\fP or \fIReplacementPrintlnFunction\fP options are left, or assigned to their default values then this check is only enabled with \fI\-std=c++23\fP or later. .sp The check doesn\(aqt do a bad job, but it\(aqs not perfect. In particular: .INDENT 0.0 .IP \(bu 2 It assumes that the format string is correct for the arguments. If you get any warnings when compiling with \fI\-Wformat\fP then misbehaviour is possible. .IP \(bu 2 At the point that the check runs, the AST contains a single \fBStringLiteral\fP for the format string and any macro expansion, token pasting, adjacent string literal concatenation and escaping has been handled. Although it\(aqs possible for the check to automatically put the escapes back, they may not be exactly as they were written (e.g. \fB\(dq\ex0a\(dq\fP will become \fB\(dq\en\(dq\fP and \fB\(dqab\(dq \(dqcd\(dq\fP will become \fB\(dqabcd\(dq\fP\&.) This is helpful since it means that the \fBPRIx\fP macros from \fB\fP are removed correctly. .IP \(bu 2 It supports field widths, precision, positional arguments, leading zeros, leading \fB+\fP, alignment and alternative forms. .IP \(bu 2 Use of any unsupported flags or specifiers will cause the entire statement to be left alone and a warning to be emitted. Particular unsupported features are: .INDENT 2.0 .IP \(bu 2 The \fB%\(aq\fP flag for thousands separators. .IP \(bu 2 The glibc extension \fB%m\fP\&. .UNINDENT .IP \(bu 2 \fBprintf\fP and similar functions return the number of characters printed. \fBstd::print\fP does not. This means that any invocations that use the return value will not be converted. Unfortunately this currently includes explicitly\-casting to \fBvoid\fP\&. Deficiencies in this check mean that any invocations inside \fBGCC\fP compound statements cannot be converted even if the resulting value is not used. .UNINDENT .sp If conversion would be incomplete or unsafe then the entire invocation will be left unchanged. .sp If the call is deemed suitable for conversion then: .INDENT 0.0 .IP \(bu 2 \fBprintf\fP, \fBfprintf\fP, \fBabsl::PrintF\fP, \fBabsl::FPrintF\fP and any functions specified by the \fIPrintfLikeFunctions\fP option or \fIFprintfLikeFunctions\fP are replaced with the function specified by the \fIReplacementPrintlnFunction\fP option if the format string ends with \fB\en\fP or \fIReplacementPrintFunction\fP otherwise. .IP \(bu 2 the format string is rewritten to use the \fBstd::formatter\fP language. If a \fB\en\fP is found at the end of the format string not preceded by \fBr\fP then it is removed and \fIReplacementPrintlnFunction\fP is used rather than \fIReplacementPrintFunction\fP\&. .IP \(bu 2 any arguments that corresponded to \fB%p\fP specifiers that \fBstd::formatter\fP wouldn\(aqt accept are wrapped in a \fBstatic_cast\fP to \fBconst void *\fP\&. .IP \(bu 2 any arguments that corresponded to \fB%s\fP specifiers where the argument is of \fBsigned char\fP or \fBunsigned char\fP type are wrapped in a \fBreinterpret_cast\fP\&. .IP \(bu 2 any arguments where the format string and the parameter differ in signedness will be wrapped in an approprate \fBstatic_cast\fP if \fIStrictMode\fP is enabled. .IP \(bu 2 any arguments that end in a call to \fBstd::string::c_str()\fP or \fBstd::string::data()\fP will have that call removed. .UNINDENT .SS Options .INDENT 0.0 .TP .B StrictMode .INDENT 7.0 .INDENT 3.5 When \fItrue\fP, the check will add casts when converting from variadic functions like \fBprintf\fP and printing signed or unsigned integer types (including fixed\-width integer types from \fB\fP, \fBptrdiff_t\fP, \fBsize_t\fP and \fBssize_t\fP) as the opposite signedness to ensure that the output matches that of \fBprintf\fP\&. This does not apply when converting from non\-variadic functions such as \fBabsl::PrintF\fP and \fBfmt::printf\fP\&. For example, with \fIStrictMode\fP enabled: .UNINDENT .UNINDENT .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C int i = \-42; unsigned int u = 0xffffffff; printf(\(dq%d %u\en\(dq, i, u); .ft P .fi .UNINDENT .UNINDENT .sp would be converted to: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C std::print(\(dq{} {}\en\(dq, static_cast(i), static_cast(u)); .ft P .fi .UNINDENT .UNINDENT .sp to ensure that the output will continue to be the unsigned representation of \fI\-42\fP and the signed representation of \fI0xffffffff\fP (often \fI4294967254\fP and \fI\-1\fP respectively.) When \fIfalse\fP (which is the default), these casts will not be added which may cause a change in the output. .UNINDENT .INDENT 0.0 .TP .B PrintfLikeFunctions A semicolon\-separated list of (fully qualified) extra function names to replace, with the requirement that the first parameter contains the printf\-style format string and the arguments to be formatted follow immediately afterwards. If neither this option nor \fIFprintfLikeFunctions\fP are set then the default value for this option is \fIprintf; absl::PrintF\fP, otherwise it is empty. .UNINDENT .INDENT 0.0 .TP .B FprintfLikeFunctions A semicolon\-separated list of (fully qualified) extra function names to replace, with the requirement that the first parameter is retained, the second parameter contains the printf\-style format string and the arguments to be formatted follow immediately afterwards. If neither this option nor \fIPrintfLikeFunctions\fP are set then the default value for this option is \fIfprintf; absl::FPrintF\fP, otherwise it is empty. .UNINDENT .INDENT 0.0 .TP .B ReplacementPrintFunction The function that will be used to replace \fBprintf\fP, \fBfprintf\fP etc. during conversion rather than the default \fBstd::print\fP when the originalformat string does not end with \fB\en\fP\&. It is expected that the function provides an interface that is compatible with \fBstd::print\fP\&. A suitable candidate would be \fBfmt::print\fP\&. .UNINDENT .INDENT 0.0 .TP .B ReplacementPrintlnFunction The function that will be used to replace \fBprintf\fP, \fBfprintf\fP etc. during conversion rather than the default \fBstd::println\fP when the original format string ends with \fB\en\fP\&. It is expected that the function provides an interface that is compatible with \fBstd::println\fP\&. A suitable candidate would be \fBfmt::println\fP\&. .UNINDENT .INDENT 0.0 .TP .B PrintHeader The header that must be included for the declaration of \fIReplacementPrintFunction\fP so that a \fB#include\fP directive can be added if required. If \fIReplacementPrintFunction\fP is \fBstd::print\fP then this option will default to \fB\fP, otherwise this option will default to nothing and no \fB#include\fP directive will be added. .UNINDENT .SS modernize\-use\-trailing\-return\-type .sp Rewrites function signatures to use a trailing return type (introduced in C++11). This transformation is purely stylistic. The return type before the function name is replaced by \fBauto\fP and inserted after the function parameter list (and qualifiers). .SS Example .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int f1(); inline int f2(int arg) noexcept; virtual float f3() const && = delete; .ft P .fi .UNINDENT .UNINDENT .sp transforms to: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C auto f1() \-> int; inline auto f2(int arg) \-> int noexcept; virtual auto f3() const && \-> float = delete; .ft P .fi .UNINDENT .UNINDENT .SS Known Limitations .sp The following categories of return types cannot be rewritten currently: .INDENT 0.0 .IP \(bu 2 function pointers .IP \(bu 2 member function pointers .IP \(bu 2 member pointers .UNINDENT .sp Unqualified names in the return type might erroneously refer to different entities after the rewrite. Preventing such errors requires a full lookup of all unqualified names present in the return type in the scope of the trailing return type location. This location includes e.g. function parameter names and members of the enclosing class (including all inherited classes). Such a lookup is currently not implemented. .sp Given the following piece of code .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct S { long long value; }; S f(unsigned S) { return {S * 2}; } class CC { int S; struct S m(); }; S CC::m() { return {0}; } .ft P .fi .UNINDENT .UNINDENT .sp a careless rewrite would produce the following output: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct S { long long value; }; auto f(unsigned S) \-> S { return {S * 2}; } // error class CC { int S; auto m() \-> struct S; }; auto CC::m() \-> S { return {0}; } // error .ft P .fi .UNINDENT .UNINDENT .sp This code fails to compile because the S in the context of f refers to the equally named function parameter. Similarly, the S in the context of m refers to the equally named class member. The check can currently only detect and avoid a clash with a function parameter name. .SS modernize\-use\-transparent\-functors .sp Prefer transparent functors to non\-transparent ones. When using transparent functors, the type does not need to be repeated. The code is easier to read, maintain and less prone to errors. It is not possible to introduce unwanted conversions. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Non\-transparent functor std::map> s; // Transparent functor. std::map> s; // Non\-transparent functor using MyFunctor = std::less; .ft P .fi .UNINDENT .UNINDENT .sp It is not always a safe transformation though. The following case will be untouched to preserve the semantics. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Non\-transparent functor std::map> s; .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B SafeMode If the option is set to \fItrue\fP, the check will not diagnose cases where using a transparent functor cannot be guaranteed to produce identical results as the original code. The default value for this option is \fIfalse\fP\&. .UNINDENT .sp This check requires using C++14 or higher to run. .SS modernize\-use\-uncaught\-exceptions .sp This check will warn on calls to \fBstd::uncaught_exception\fP and replace them with calls to \fBstd::uncaught_exceptions\fP, since \fBstd::uncaught_exception\fP was deprecated in C++17. .sp Below are a few examples of what kind of occurrences will be found and what they will be replaced with. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #define MACRO1 std::uncaught_exception #define MACRO2 std::uncaught_exception int uncaught_exception() { return 0; } int main() { int res; res = uncaught_exception(); // No warning, since it is not the deprecated function from namespace std res = MACRO2(); // Warning, but will not be replaced res = std::uncaught_exception(); // Warning and replaced using std::uncaught_exception; // Warning and replaced res = uncaught_exception(); // Warning and replaced } .ft P .fi .UNINDENT .UNINDENT .sp After applying the fixes the code will look like the following: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #define MACRO1 std::uncaught_exception #define MACRO2 std::uncaught_exception int uncaught_exception() { return 0; } int main() { int res; res = uncaught_exception(); res = MACRO2(); res = std::uncaught_exceptions(); using std::uncaught_exceptions; res = uncaught_exceptions(); } .ft P .fi .UNINDENT .UNINDENT .SS modernize\-use\-using .sp The check converts the usage of \fBtypedef\fP with \fBusing\fP keyword. .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C typedef int variable; class Class{}; typedef void (Class::* MyPtrType)() const; typedef struct { int a; } R_t, *R_p; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C using variable = int; class Class{}; using MyPtrType = void (Class::*)() const; using R_t = struct { int a; }; using R_p = R_t*; .ft P .fi .UNINDENT .UNINDENT .sp This check requires using C++11 or higher to run. .SS Options .INDENT 0.0 .TP .B IgnoreMacros If set to \fItrue\fP, the check will not give warnings inside macros. Default is \fItrue\fP\&. .UNINDENT .SS mpi\-buffer\-deref .sp This check verifies if a buffer passed to an MPI (Message Passing Interface) function is sufficiently dereferenced. Buffers should be passed as a single pointer or array. As MPI function signatures specify \fBvoid *\fP for their buffer types, insufficiently dereferenced buffers can be passed, like for example as double pointers or multidimensional arrays, without a compiler warning emitted. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // A double pointer is passed to the MPI function. char *buf; MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD); // A multidimensional array is passed to the MPI function. short buf[1][1]; MPI_Send(buf, 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD); // A pointer to an array is passed to the MPI function. short *buf[1]; MPI_Send(buf, 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD); .ft P .fi .UNINDENT .UNINDENT .SS mpi\-type\-mismatch .sp This check verifies if buffer type and MPI (Message Passing Interface) datatype pairs match for used MPI functions. All MPI datatypes defined by the MPI standard (3.1) are verified by this check. User defined typedefs, custom MPI datatypes and null pointer constants are skipped, in the course of verification. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // In this case, the buffer type matches MPI datatype. char buf; MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD); // In the following case, the buffer type does not match MPI datatype. int buf; MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD); .ft P .fi .UNINDENT .UNINDENT .SS objc\-assert\-equals .sp Finds improper usages of \fIXCTAssertEqual\fP and \fIXCTAssertNotEqual\fP and replaces them with \fIXCTAssertEqualObjects\fP or \fIXCTAssertNotEqualObjects\fP\&. .sp This makes tests less fragile, as many improperly rely on pointer equality for strings that have equal values. This assumption is not guarantted by the language. .SS objc\-avoid\-nserror\-init .sp Finds improper initialization of \fBNSError\fP objects. .sp According to Apple developer document, we should always use factory method \fBerrorWithDomain:code:userInfo:\fP to create new NSError objects instead of \fB[NSError alloc] init]\fP\&. Otherwise it will lead to a warning message during runtime. .sp The corresponding information about \fBNSError\fP creation: \fI\%https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/CreateCustomizeNSError/CreateCustomizeNSError.html\fP .SS objc\-dealloc\-in\-category .sp Finds implementations of \fB\-dealloc\fP in Objective\-C categories. The category implementation will override any \fB\-dealloc\fP in the class implementation, potentially causing issues. .sp Classes implement \fB\-dealloc\fP to perform important actions to deallocate an object. If a category on the class implements \fB\-dealloc\fP, it will override the class\(aqs implementation and unexpected deallocation behavior may occur. .SS objc\-forbidden\-subclassing .sp Finds Objective\-C classes which are subclasses of classes which are not designed to be subclassed. .sp By default, includes a list of Objective\-C classes which are publicly documented as not supporting subclassing. .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 Instead of using this check, for code under your control, you should add \fB__attribute__((objc_subclassing_restricted))\fP before your \fB@interface\fP declarations to ensure the compiler prevents others from subclassing your Objective\-C classes. See \fI\%https://clang.llvm.org/docs/AttributeReference.html#objc\-subclassing\-restricted\fP .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B ForbiddenSuperClassNames Semicolon\-separated list of names of Objective\-C classes which do not support subclassing. .sp Defaults to \fIABNewPersonViewController;ABPeoplePickerNavigationController;ABPersonViewController;ABUnknownPersonViewController;NSHashTable;NSMapTable;NSPointerArray;NSPointerFunctions;NSTimer;UIActionSheet;UIAlertView;UIImagePickerController;UITextInputMode;UIWebView\fP\&. .UNINDENT .SS objc\-missing\-hash .sp Finds Objective\-C implementations that implement \fB\-isEqual:\fP without also appropriately implementing \fB\-hash\fP\&. .sp Apple documentation highlights that objects that are equal must have the same hash value: \fI\%https://developer.apple.com/documentation/objectivec/1418956\-nsobject/1418795\-isequal?language=objc\fP .sp Note that the check only verifies the presence of \fB\-hash\fP in scenarios where its omission could result in unexpected behavior. The verification of the implementation of \fB\-hash\fP is the responsibility of the developer, e.g., through the addition of unit tests to verify the implementation. .SS objc\-nsdate\-formatter .sp When \fBNSDateFormatter\fP is used to convert an \fBNSDate\fP type to a \fBString\fP type, the user can specify a custom format string. Certain format specifiers are undesirable despite being legal. See \fI\%http://www.unicode.org/reports/tr35/tr35\-dates.html#Date_Format_Patterns\fP for all legal date patterns. .sp This checker reports as warnings the following string patterns in a date format specifier: .INDENT 0.0 .IP 1. 3 yyyy + ww : Calendar year specified with week of a week year (unless YYYY is also specified). .INDENT 3.0 .IP \(bu 2 .nf \fBExample 1:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIyyyy\-ww\fP; Output string: \fI2014\-01\fP (Wrong because it’s not the first week of 2014) .fi .sp .IP \(bu 2 .nf \fBExample 2:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIdd\-MM\-yyyy (ww\-YYYY)\fP; Output string: \fI29\-12\-2014 (01\-2015)\fP (This is correct) .fi .sp .UNINDENT .IP 2. 3 F without ee/EE : Numeric day of week in a month without actual day. .INDENT 3.0 .IP \(bu 2 .nf \fBExample:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIF\-MM\fP; Output string: \fI5\-12\fP (Wrong because it reads as \fI5th ___ of Dec\fP in English) .fi .sp .UNINDENT .IP 3. 3 F without MM : Numeric day of week in a month without month. .INDENT 3.0 .IP \(bu 2 .nf \fBExample:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIF\-EE\fP Output string: \fI5\-Mon\fP (Wrong because it reads as \fI5th Mon of ___\fP in English) .fi .sp .UNINDENT .IP 4. 3 WW without MM : Week of the month without the month. .INDENT 3.0 .IP \(bu 2 .nf \fBExample:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIWW\-yyyy\fP Output string: \fI05\-2014\fP (Wrong because it reads as \fI5th Week of ___\fP in English) .fi .sp .UNINDENT .IP 5. 3 YYYY + QQ : Week year specified with quarter of normal year (unless yyyy is also specified). .INDENT 3.0 .IP \(bu 2 .nf \fBExample 1:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIYYYY\-QQ\fP Output string: \fI2015\-04\fP (Wrong because it’s not the 4th quarter of 2015) .fi .sp .IP \(bu 2 .nf \fBExample 2:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIww\-YYYY (QQ\-yyyy)\fP Output string: \fI01\-2015 (04\-2014)\fP (This is correct) .fi .sp .UNINDENT .IP 6. 3 YYYY + MM : Week year specified with Month of a calendar year (unless yyyy is also specified). .INDENT 3.0 .IP \(bu 2 .nf \fBExample 1:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIYYYY\-MM\fP Output string: \fI2015\-12\fP (Wrong because it’s not the 12th month of 2015) .fi .sp .IP \(bu 2 .nf \fBExample 2:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIww\-YYYY (MM\-yyyy)\fP Output string: \fI01\-2015 (12\-2014)\fP (This is correct) .fi .sp .UNINDENT .IP 7. 3 YYYY + DD : Week year with day of a calendar year (unless yyyy is also specified). .INDENT 3.0 .IP \(bu 2 .nf \fBExample 1:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIYYYY\-DD\fP Output string: \fI2015\-363\fP (Wrong because it’s not the 363rd day of 2015) .fi .sp .IP \(bu 2 .nf \fBExample 2:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIww\-YYYY (DD\-yyyy)\fP Output string: \fI01\-2015 (363\-2014)\fP (This is correct) .fi .sp .UNINDENT .IP 8. 3 YYYY + WW : Week year with week of a calendar year (unless yyyy is also specified). .INDENT 3.0 .IP \(bu 2 .nf \fBExample 1:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIYYYY\-WW\fP Output string: \fI2015\-05\fP (Wrong because it’s not the 5th week of 2015) .fi .sp .IP \(bu 2 .nf \fBExample 2:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIww\-YYYY (WW\-MM\-yyyy)\fP Output string: \fI01\-2015 (05\-12\-2014)\fP (This is correct) .fi .sp .UNINDENT .IP 9. 3 YYYY + F : Week year with day of week in a calendar month (unless yyyy is also specified). .INDENT 3.0 .IP \(bu 2 .nf \fBExample 1:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIYYYY\-ww\-F\-EE\fP Output string: \fI2015\-01\-5\-Mon\fP (Wrong because it’s not the 5th Monday of January in 2015) .fi .sp .IP \(bu 2 .nf \fBExample 2:\fP Input Date: \fI29 December 2014\fP ; Format String: \fIww\-YYYY (F\-EE\-MM\-yyyy)\fP Output string: \fI01\-2015 (5\-Mon\-12\-2014)\fP (This is correct) .fi .sp .UNINDENT .UNINDENT .SS objc\-nsinvocation\-argument\-lifetime .sp Finds calls to \fBNSInvocation\fP methods under ARC that don\(aqt have proper argument object lifetimes. When passing Objective\-C objects as parameters to the \fBNSInvocation\fP methods \fBgetArgument:atIndex:\fP and \fBgetReturnValue:\fP, the values are copied by value into the argument pointer, which leads to incorrect releasing behavior if the object pointers are not declared \fB__unsafe_unretained\fP\&. .sp For code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C id arg; [invocation getArgument:&arg atIndex:2]; __strong id returnValue; [invocation getReturnValue:&returnValue]; .ft P .fi .UNINDENT .UNINDENT .sp The fix will be: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C __unsafe_unretained id arg; [invocation getArgument:&arg atIndex:2]; __unsafe_unretained id returnValue; [invocation getReturnValue:&returnValue]; .ft P .fi .UNINDENT .UNINDENT .sp The check will warn on being passed instance variable references that have lifetimes other than \fB__unsafe_unretained\fP, but does not propose a fix: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // \(dqid _returnValue\(dq is declaration of instance variable of class. [invocation getReturnValue:&self\->_returnValue]; .ft P .fi .UNINDENT .UNINDENT .SS objc\-property\-declaration .sp Finds property declarations in Objective\-C files that do not follow the pattern of property names in Apple\(aqs programming guide. The property name should be in the format of Lower Camel Case. .sp For code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C @property(nonatomic, assign) int LowerCamelCase; .ft P .fi .UNINDENT .UNINDENT .sp The fix will be: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C @property(nonatomic, assign) int lowerCamelCase; .ft P .fi .UNINDENT .UNINDENT .sp The check will only fix \(aqCamelCase\(aq to \(aqcamelCase\(aq. In some other cases we will only provide warning messages since the property name could be complicated. Users will need to come up with a proper name by their own. .sp This check also accepts special acronyms as prefixes or suffixes. Such prefixes or suffixes will suppress the Lower Camel Case check according to the guide: \fI\%https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingBasics.html#//apple_ref/doc/uid/20001281\-1002931\-BBCFHEAB\fP .sp For a full list of well\-known acronyms: \fI\%https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/APIAbbreviations.html#//apple_ref/doc/uid/20001285\-BCIHCGAE\fP .sp The corresponding style rule: \fI\%https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingIvarsAndTypes.html#//apple_ref/doc/uid/20001284\-1001757\fP .sp The check will also accept property declared in category with a prefix of lowercase letters followed by a \(aq_\(aq to avoid naming conflict. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C @property(nonatomic, assign) int abc_lowerCamelCase; .ft P .fi .UNINDENT .UNINDENT .sp The corresponding style rule: \fI\%https://developer.apple.com/library/content/qa/qa1908/_index.html\fP .SS objc\-super\-self .sp Finds invocations of \fB\-self\fP on super instances in initializers of subclasses of \fBNSObject\fP and recommends calling a superclass initializer instead. .sp Invoking \fB\-self\fP on super instances in initializers is a common programmer error when the programmer\(aqs original intent is to call a superclass initializer. Failing to call a superclass initializer breaks initializer chaining and can result in invalid object initialization. .SS openmp\-exception\-escape .sp Analyzes OpenMP Structured Blocks and checks that no exception escapes out of the Structured Block it was thrown in. .sp As per the OpenMP specification, a structured block is an executable statement, possibly compound, with a single entry at the top and a single exit at the bottom. Which means, \fBthrow\fP may not be used to \(aqexit\(aq out of the structured block. If an exception is not caught in the same structured block it was thrown in, the behavior is undefined. .sp FIXME: this check does not model SEH, \fBsetjmp\fP/\fBlongjmp\fP\&. .sp WARNING! This check may be expensive on large source files. .SS Options .INDENT 0.0 .TP .B IgnoredExceptions Comma\-separated list containing type names which are not counted as thrown exceptions in the check. Default value is an empty string. .UNINDENT .SS openmp\-use\-default\-none .sp Finds OpenMP directives that are allowed to contain a \fBdefault\fP clause, but either don\(aqt specify it or the clause is specified but with the kind other than \fBnone\fP, and suggests to use the \fBdefault(none)\fP clause. .sp Using \fBdefault(none)\fP clause forces developers to explicitly specify data sharing attributes for the variables referenced in the construct, thus making it obvious which variables are referenced, and what is their data sharing attribute, thus increasing readability and possibly making errors easier to spot. .SS Example .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // \(ga\(gafor\(ga\(ga directive cannot have \(ga\(gadefault\(ga\(ga clause, no diagnostics. void n0(const int a) { #pragma omp for for (int b = 0; b < a; b++) ; } // \(ga\(gaparallel\(ga\(ga directive. // \(ga\(gaparallel\(ga\(ga directive can have \(ga\(gadefault\(ga\(ga clause, but said clause is not // specified, diagnosed. void p0_0() { #pragma omp parallel ; // WARNING: OpenMP directive \(ga\(gaparallel\(ga\(ga does not specify \(ga\(gadefault\(ga\(ga // clause. Consider specifying \(ga\(gadefault(none)\(ga\(ga clause. } // \(ga\(gaparallel\(ga\(ga directive can have \(ga\(gadefault\(ga\(ga clause, and said clause is // specified, with \(ga\(ganone\(ga\(ga kind, all good. void p0_1() { #pragma omp parallel default(none) ; } // \(ga\(gaparallel\(ga\(ga directive can have \(ga\(gadefault\(ga\(ga clause, and said clause is // specified, but with \(ga\(gashared\(ga\(ga kind, which is not \(ga\(ganone\(ga\(ga, diagnose. void p0_2() { #pragma omp parallel default(shared) ; // WARNING: OpenMP directive \(ga\(gaparallel\(ga\(ga specifies \(ga\(gadefault(shared)\(ga\(ga // clause. Consider using \(ga\(gadefault(none)\(ga\(ga clause instead. } // \(ga\(gaparallel\(ga\(ga directive can have \(ga\(gadefault\(ga\(ga clause, and said clause is // specified, but with \(ga\(gafirstprivate\(ga\(ga kind, which is not \(ga\(ganone\(ga\(ga, diagnose. void p0_3() { #pragma omp parallel default(firstprivate) ; // WARNING: OpenMP directive \(ga\(gaparallel\(ga\(ga specifies \(ga\(gadefault(firstprivate)\(ga\(ga // clause. Consider using \(ga\(gadefault(none)\(ga\(ga clause instead. } .ft P .fi .UNINDENT .UNINDENT .SS performance\-avoid\-endl .sp Checks for uses of \fBstd::endl\fP on streams and suggests using the newline character \fB\(aq\en\(aq\fP instead. .sp Rationale: Using \fBstd::endl\fP on streams can be less efficient than using the newline character \fB\(aq\en\(aq\fP because \fBstd::endl\fP performs two operations: it writes a newline character to the output stream and then flushes the stream buffer. Writing a single newline character using \fB\(aq\en\(aq\fP does not trigger a flush, which can improve performance. In addition, flushing the stream buffer can cause additional overhead when working with streams that are buffered. .sp Example: .sp Consider the following code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include int main() { std::cout << \(dqHello\(dq << std::endl; } .ft P .fi .UNINDENT .UNINDENT .sp Which gets transformed into: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include int main() { std::cout << \(dqHello\(dq << \(aq\en\(aq; } .ft P .fi .UNINDENT .UNINDENT .sp This code writes a single newline character to the \fBstd::cout\fP stream without flushing the stream buffer. .sp Additionally, it is important to note that the standard C++ streams (like \fBstd::cerr\fP, \fBstd::wcerr\fP, \fBstd::clog\fP and \fBstd::wclog\fP) always flush after a write operation, unless \fBstd::ios_base::sync_with_stdio\fP is set to \fBfalse\fP\&. regardless of whether \fBstd::endl\fP or \fB\(aq\en\(aq\fP is used. Therefore, using \fB\(aq\en\(aq\fP with these streams will not result in any performance gain, but it is still recommended to use \fB\(aq\en\(aq\fP for consistency and readability. .sp If you do need to flush the stream buffer, you can use \fBstd::flush\fP explicitly like this: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include int main() { std::cout << \(dqHello\en\(dq << std::flush; } .ft P .fi .UNINDENT .UNINDENT .SS performance\-faster\-string\-find .sp Optimize calls to \fBstd::string::find()\fP and friends when the needle passed is a single character string literal. The character literal overload is more efficient. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C str.find(\(dqA\(dq); // becomes str.find(\(aqA\(aq); .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B StringLikeClasses Semicolon\-separated list of names of string\-like classes. By default only \fB::std::basic_string\fP and \fB::std::basic_string_view\fP are considered. The check will only consider member functions named \fBfind\fP, \fBrfind\fP, \fBfind_first_of\fP, \fBfind_first_not_of\fP, \fBfind_last_of\fP, or \fBfind_last_not_of\fP within these classes. .UNINDENT .SS performance\-for\-range\-copy .sp Finds C++11 for ranges where the loop variable is copied in each iteration but it would suffice to obtain it by const reference. .sp The check is only applied to loop variables of types that are expensive to copy which means they are not trivially copyable or have a non\-trivial copy constructor or destructor. .sp To ensure that it is safe to replace the copy with a const reference the following heuristic is employed: .INDENT 0.0 .IP 1. 3 The loop variable is const qualified. .IP 2. 3 The loop variable is not const, but only const methods or operators are invoked on it, or it is used as const reference or value argument in constructors or function calls. .UNINDENT .SS Options .INDENT 0.0 .TP .B WarnOnAllAutoCopies When \fItrue\fP, warns on any use of \fIauto\fP as the type of the range\-based for loop variable. Default is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B AllowedTypes A semicolon\-separated list of names of types allowed to be copied in each iteration. Regular expressions are accepted, e.g. \fI[Rr]ef(erence)?$\fP matches every type with suffix \fIRef\fP, \fIref\fP, \fIReference\fP and \fIreference\fP\&. The default is empty. If a name in the list contains the sequence \fI::\fP it is matched against the qualified typename (i.e. \fInamespace::Type\fP, otherwise it is matched against only the type name (i.e. \fIType\fP). .UNINDENT .SS performance\-implicit\-cast\-in\-loop .sp This check has been renamed to \fI\%performance\-implicit\-conversion\-in\-loop\fP\&. .SS performance\-implicit\-conversion\-in\-loop .sp This warning appears in a range\-based loop with a loop variable of const ref type where the type of the variable does not match the one returned by the iterator. This means that an implicit conversion happens, which can for example result in expensive deep copies. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C map> my_map; for (const pair>& p : my_map) {} // The iterator type is in fact pair>, which means // that the compiler added a conversion, resulting in a copy of the vectors. .ft P .fi .UNINDENT .UNINDENT .sp The easiest solution is usually to use \fBconst auto&\fP instead of writing the type manually. .SS performance\-inefficient\-algorithm .sp Warns on inefficient use of STL algorithms on associative containers. .sp Associative containers implement some of the algorithms as methods which should be preferred to the algorithms in the algorithm header. The methods can take advantage of the order of the elements. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::set s; auto it = std::find(s.begin(), s.end(), 43); // becomes auto it = s.find(43); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::set s; auto c = std::count(s.begin(), s.end(), 43); // becomes auto c = s.count(43); .ft P .fi .UNINDENT .UNINDENT .SS performance\-inefficient\-string\-concatenation .sp This check warns about the performance overhead arising from concatenating strings using the \fBoperator+\fP, for instance: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string a(\(dqFoo\(dq), b(\(dqBar\(dq); a = a + b; .ft P .fi .UNINDENT .UNINDENT .sp Instead of this structure you should use \fBoperator+=\fP or \fBstd::string\fP\(aqs (\fBstd::basic_string\fP) class member function \fBappend()\fP\&. For instance: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string a(\(dqFoo\(dq), b(\(dqBaz\(dq); for (int i = 0; i < 20000; ++i) { a = a + \(dqBar\(dq + b; } .ft P .fi .UNINDENT .UNINDENT .sp Could be rewritten in a greatly more efficient way like: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::string a(\(dqFoo\(dq), b(\(dqBaz\(dq); for (int i = 0; i < 20000; ++i) { a.append(\(dqBar\(dq).append(b); } .ft P .fi .UNINDENT .UNINDENT .sp And this can be rewritten too: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(const std::string&) {} std::string a(\(dqFoo\(dq), b(\(dqBaz\(dq); void g() { f(a + \(dqBar\(dq + b); } .ft P .fi .UNINDENT .UNINDENT .sp In a slightly more efficient way like: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(const std::string&) {} std::string a(\(dqFoo\(dq), b(\(dqBaz\(dq); void g() { f(std::string(a).append(\(dqBar\(dq).append(b)); } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B StrictMode When \fIfalse\fP, the check will only check the string usage in \fBwhile\fP, \fBfor\fP and \fBfor\-range\fP statements. Default is \fIfalse\fP\&. .UNINDENT .SS performance\-inefficient\-vector\-operation .sp Finds possible inefficient \fBstd::vector\fP operations (e.g. \fBpush_back\fP, \fBemplace_back\fP) that may cause unnecessary memory reallocations. .sp It can also find calls that add element to protobuf repeated field in a loop without calling Reserve() before the loop. Calling Reserve() first can avoid unnecessary memory reallocations. .sp Currently, the check only detects following kinds of loops with a single statement body: .INDENT 0.0 .IP \(bu 2 Counter\-based for loops start with 0: .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector v; for (int i = 0; i < n; ++i) { v.push_back(n); // This will trigger the warning since the push_back may cause multiple // memory reallocations in v. This can be avoid by inserting a \(aqreserve(n)\(aq // statement before the for statement. } SomeProto p; for (int i = 0; i < n; ++i) { p.add_xxx(n); // This will trigger the warning since the add_xxx may cause multiple memory // reallocations. This can be avoid by inserting a // \(aqp.mutable_xxx().Reserve(n)\(aq statement before the for statement. } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 For\-range loops like \fBfor (range\-declaration : range_expression)\fP, the type of \fBrange_expression\fP can be \fBstd::vector\fP, \fBstd::array\fP, \fBstd::deque\fP, \fBstd::set\fP, \fBstd::unordered_set\fP, \fBstd::map\fP, \fBstd::unordered_set\fP: .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C std::vector data; std::vector v; for (auto element : data) { v.push_back(element); // This will trigger the warning since the \(aqpush_back\(aq may cause multiple // memory reallocations in v. This can be avoid by inserting a // \(aqreserve(data.size())\(aq statement before the for statement. } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B VectorLikeClasses Semicolon\-separated list of names of vector\-like classes. By default only \fB::std::vector\fP is considered. .UNINDENT .INDENT 0.0 .TP .B EnableProto When \fItrue\fP, the check will also warn on inefficient operations for proto repeated fields. Otherwise, the check only warns on inefficient vector operations. Default is \fIfalse\fP\&. .UNINDENT .SS performance\-move\-const\-arg .sp The check warns .INDENT 0.0 .IP \(bu 2 if \fBstd::move()\fP is called with a constant argument, .IP \(bu 2 if \fBstd::move()\fP is called with an argument of a trivially\-copyable type, .IP \(bu 2 if the result of \fBstd::move()\fP is passed as a const reference argument. .UNINDENT .sp In all three cases, the check will suggest a fix that removes the \fBstd::move()\fP\&. .sp Here are examples of each of the three cases: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const string s; return std::move(s); // Warning: std::move of the const variable has no effect int x; return std::move(x); // Warning: std::move of the variable of a trivially\-copyable type has no effect void f(const string &s); string s; f(std::move(s)); // Warning: passing result of std::move as a const reference argument; no move will actually happen .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B CheckTriviallyCopyableMove If \fItrue\fP, enables detection of trivially copyable types that do not have a move constructor. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B CheckMoveToConstRef If \fItrue\fP, enables detection of \fIstd::move()\fP passed as a const reference argument. Default is \fItrue\fP\&. .UNINDENT .SS performance\-move\-constructor\-init .sp \(dqcert\-oop11\-cpp\(dq redirects here as an alias for this check. .sp The check flags user\-defined move constructors that have a ctor\-initializer initializing a member or base class through a copy constructor instead of a move constructor. .SS performance\-no\-automatic\-move .sp Finds local variables that cannot be automatically moved due to constness. .sp Under \fI\%certain conditions\fP, local values are automatically moved out when returning from a function. A common mistake is to declare local \fBlvalue\fP variables \fBconst\fP, which prevents the move. .sp Example \fI\%[1]\fP: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C StatusOr> Cool() { std::vector obj = ...; return obj; // calls StatusOr::StatusOr(std::vector&&) } StatusOr> NotCool() { const std::vector obj = ...; return obj; // calls \(gaStatusOr::StatusOr(const std::vector&)\(ga } .ft P .fi .UNINDENT .UNINDENT .sp The former version (\fBCool\fP) should be preferred over the latter (\fBNotCool\fP) as it will avoid allocations and potentially large memory copies. .SS Semantics .sp In the example above, \fBStatusOr::StatusOr(T&&)\fP have the same semantics as long as the copy and move constructors for \fBT\fP have the same semantics. Note that there is no guarantee that \fBS::S(T&&)\fP and \fBS::S(const T&)\fP have the same semantics for any single \fBS\fP, so we\(aqre not providing automated fixes for this check, and judgement should be exerted when making the suggested changes. .SS \-Wreturn\-std\-move .sp Another case where the move cannot happen is the following: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C StatusOr> Uncool() { std::vector&& obj = ...; return obj; // calls \(gaStatusOr::StatusOr(const std::vector&)\(ga } .ft P .fi .UNINDENT .UNINDENT .sp In that case the fix is more consensual: just \fIreturn std::move(obj)\fP\&. This is handled by the \fI\-Wreturn\-std\-move\fP warning. .SS performance\-no\-int\-to\-ptr .sp Diagnoses every integer to pointer cast. .sp While casting an (integral) pointer to an integer is obvious \- you just get the integral value of the pointer, casting an integer to an (integral) pointer is deceivingly different. While you will get a pointer with that integral value, if you got that integral value via a pointer\-to\-integer cast originally, the new pointer will lack the provenance information from the original pointer. .sp So while (integral) pointer to integer casts are effectively no\-ops, and are transparent to the optimizer, integer to (integral) pointer casts are \fINOT\fP transparent, and may conceal information from optimizer. .sp While that may be the intention, it is not always so. For example, let\(aqs take a look at a routine to align the pointer up to the multiple of 16: The obvious, naive implementation for that is: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C char* src(char* maybe_underbiased_ptr) { uintptr_t maybe_underbiased_intptr = (uintptr_t)maybe_underbiased_ptr; uintptr_t aligned_biased_intptr = maybe_underbiased_intptr + 15; uintptr_t aligned_intptr = aligned_biased_intptr & (~15); return (char*)aligned_intptr; // warning: avoid integer to pointer casts [performance\-no\-int\-to\-ptr] } .ft P .fi .UNINDENT .UNINDENT .sp The check will rightfully diagnose that cast. .sp But when provenance concealment is not the goal of the code, but an accident, this example can be rewritten as follows, without using integer to pointer cast: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C char* tgt(char* maybe_underbiased_ptr) { uintptr_t maybe_underbiased_intptr = (uintptr_t)maybe_underbiased_ptr; uintptr_t aligned_biased_intptr = maybe_underbiased_intptr + 15; uintptr_t aligned_intptr = aligned_biased_intptr & (~15); uintptr_t bias = aligned_intptr \- maybe_underbiased_intptr; return maybe_underbiased_ptr + bias; } .ft P .fi .UNINDENT .UNINDENT .SS performance\-noexcept\-destructor .sp The check flags user\-defined destructors marked with \fBnoexcept(expr)\fP where \fBexpr\fP evaluates to \fBfalse\fP (but is not a \fBfalse\fP literal itself). .sp When a destructor is marked as \fBnoexcept\fP, it assures the compiler that no exceptions will be thrown during the destruction of an object, which allows the compiler to perform certain optimizations such as omitting exception handling code. .SS performance\-noexcept\-move\-constructor .sp The check flags user\-defined move constructors and assignment operators not marked with \fBnoexcept\fP or marked with \fBnoexcept(expr)\fP where \fBexpr\fP evaluates to \fBfalse\fP (but is not a \fBfalse\fP literal itself). .sp Move constructors of all the types used with STL containers, for example, need to be declared \fBnoexcept\fP\&. Otherwise STL will choose copy constructors instead. The same is valid for move assignment operations. .SS performance\-noexcept\-swap .sp The check flags user\-defined swap functions not marked with \fBnoexcept\fP or marked with \fBnoexcept(expr)\fP where \fBexpr\fP evaluates to \fBfalse\fP (but is not a \fBfalse\fP literal itself). .sp When a swap function is marked as \fBnoexcept\fP, it assures the compiler that no exceptions will be thrown during the swapping of two objects, which allows the compiler to perform certain optimizations such as omitting exception handling code. .SS performance\-trivially\-destructible .sp Finds types that could be made trivially\-destructible by removing out\-of\-line defaulted destructor declarations. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct A: TrivialType { ~A(); // Makes A non\-trivially\-destructible. TrivialType trivial_fields; }; A::~A() = default; .ft P .fi .UNINDENT .UNINDENT .SS performance\-type\-promotion\-in\-math\-fn .sp Finds calls to C math library functions (from \fBmath.h\fP or, in C++, \fBcmath\fP) with implicit \fBfloat\fP to \fBdouble\fP promotions. .sp For example, warns on \fB::sin(0.f)\fP, because this function\(aqs parameter is a double. You probably meant to call \fBstd::sin(0.f)\fP (in C++), or \fBsinf(0.f)\fP (in C). .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C float a; asin(a); // becomes float a; std::asin(a); .ft P .fi .UNINDENT .UNINDENT .SS performance\-unnecessary\-copy\-initialization .sp Finds local variable declarations that are initialized using the copy constructor of a non\-trivially\-copyable type but it would suffice to obtain a const reference. .sp The check is only applied if it is safe to replace the copy by a const reference. This is the case when the variable is const qualified or when it is only used as a const, i.e. only const methods or operators are invoked on it, or it is used as const reference or value argument in constructors or function calls. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const string& constReference(); void Function() { // The warning will suggest making this a const reference. const string UnnecessaryCopy = constReference(); } struct Foo { const string& name() const; }; void Function(const Foo& foo) { // The warning will suggest making this a const reference. string UnnecessaryCopy1 = foo.name(); UnnecessaryCopy1.find(\(dqbar\(dq); // The warning will suggest making this a const reference. string UnnecessaryCopy2 = UnnecessaryCopy1; UnnecessaryCopy2.find(\(dqbar\(dq); } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B AllowedTypes A semicolon\-separated list of names of types allowed to be initialized by copying. Regular expressions are accepted, e.g. \fI[Rr]ef(erence)?$\fP matches every type with suffix \fIRef\fP, \fIref\fP, \fIReference\fP and \fIreference\fP\&. The default is empty. If a name in the list contains the sequence \fI::\fP it is matched against the qualified typename (i.e. \fInamespace::Type\fP, otherwise it is matched against only the type name (i.e. \fIType\fP). .UNINDENT .INDENT 0.0 .TP .B ExcludedContainerTypes A semicolon\-separated list of names of types whose methods are allowed to return the const reference the variable is copied from. When an expensive to copy variable is copy initialized by the return value from a type on this list the check does not trigger. This can be used to exclude types known to be const incorrect or where the lifetime or immutability of returned references is not tied to mutations of the container. An example are view types that don\(aqt own the underlying data. Like for \fIAllowedTypes\fP above, regular expressions are accepted and the inclusion of \fI::\fP determines whether the qualified typename is matched or not. .UNINDENT .SS performance\-unnecessary\-value\-param .sp Flags value parameter declarations of expensive to copy types that are copied for each invocation but it would suffice to pass them by const reference. .sp The check is only applied to parameters of types that are expensive to copy which means they are not trivially copyable or have a non\-trivial copy constructor or destructor. .sp To ensure that it is safe to replace the value parameter with a const reference the following heuristic is employed: .INDENT 0.0 .IP 1. 3 the parameter is const qualified; .IP 2. 3 the parameter is not const, but only const methods or operators are invoked on it, or it is used as const reference or value argument in constructors or function calls. .UNINDENT .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(const string Value) { // The warning will suggest making Value a reference. } void g(ExpensiveToCopy Value) { // The warning will suggest making Value a const reference. Value.ConstMethd(); ExpensiveToCopy Copy(Value); } .ft P .fi .UNINDENT .UNINDENT .sp If the parameter is not const, only copied or assigned once and has a non\-trivial move\-constructor or move\-assignment operator respectively the check will suggest to move it. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void setValue(string Value) { Field = Value; } .ft P .fi .UNINDENT .UNINDENT .sp Will become: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include void setValue(string Value) { Field = std::move(Value); } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IncludeStyle A string specifying which include\-style is used, \fIllvm\fP or \fIgoogle\fP\&. Default is \fIllvm\fP\&. .UNINDENT .INDENT 0.0 .TP .B AllowedTypes A semicolon\-separated list of names of types allowed to be passed by value. Regular expressions are accepted, e.g. \fI[Rr]ef(erence)?$\fP matches every type with suffix \fIRef\fP, \fIref\fP, \fIReference\fP and \fIreference\fP\&. The default is empty. If a name in the list contains the sequence \fI::\fP it is matched against the qualified typename (i.e. \fInamespace::Type\fP, otherwise it is matched against only the type name (i.e. \fIType\fP). .UNINDENT .SS portability\-restrict\-system\-includes .sp Checks to selectively allow or disallow a configurable list of system headers. .sp For example: .sp In order to \fBonly\fP allow \fIzlib.h\fP from the system you would set the options to \fI\-*,zlib.h\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include // Bad: disallowed system header. #include // Bad: disallowed system header. #include // Good: allowed system header. #include \(dqsrc/myfile.h\(dq // Good: non\-system header always allowed. .ft P .fi .UNINDENT .UNINDENT .sp In order to allow everything \fBexcept\fP \fIzlib.h\fP from the system you would set the options to \fI*,\-zlib.h\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include // Good: allowed system header. #include // Good: allowed system header. #include // Bad: disallowed system header. #include \(dqsrc/myfile.h\(dq // Good: non\-system header always allowed. .ft P .fi .UNINDENT .UNINDENT .sp Since the options support globbing you can use wildcarding to allow groups of headers. .sp \fI\-*,openssl/*.h\fP will allow all openssl headers but disallow any others. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include // Bad: disallowed system header. #include // Good: allowed system header. #include // Good: allowed system header. #include // Bad: disallowed system header. #include \(dqsrc/myfile.h\(dq // Good: non\-system header always allowed. .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B Includes A string containing a comma separated glob list of allowed include filenames. Similar to the \-checks glob list for running clang\-tidy itself, the two wildcard characters are \fI*\fP and \fI\-\fP, to include and exclude globs, respectively. The default is \fI*\fP, which allows all includes. .UNINDENT .SS portability\-simd\-intrinsics .sp Finds SIMD intrinsics calls and suggests \fBstd::experimental::simd\fP (\fI\%P0214\fP) alternatives. .sp If the option \fI\%Suggest\fP is set to \fItrue\fP, for .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C _mm_add_epi32(a, b); // x86 vec_add(a, b); // Power .ft P .fi .UNINDENT .UNINDENT .sp the check suggests an alternative: \fBoperator+\fP on \fBstd::experimental::simd\fP objects. .sp Otherwise, it just complains the intrinsics are non\-portable (and there are \fI\%P0214\fP alternatives). .sp Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX, ARM NEON). It is common that SIMD code implementing the same algorithm, is written in multiple target\-dispatching pieces to optimize for different architectures or micro\-architectures. .sp The C++ standard proposal \fI\%P0214\fP and its extensions cover many common SIMD operations. By migrating from target\-dependent intrinsics to \fI\%P0214\fP operations, the SIMD code can be simplified and pieces for different targets can be unified. .sp Refer to \fI\%P0214\fP for introduction and motivation for the data\-parallel standard library. .SS Options .INDENT 0.0 .TP .B Suggest If this option is set to \fItrue\fP (default is \fIfalse\fP), the check will suggest \fI\%P0214\fP alternatives, otherwise it only points out the intrinsic function is non\-portable. .UNINDENT .INDENT 0.0 .TP .B Std The namespace used to suggest \fI\%P0214\fP alternatives. If not specified, \fIstd::\fP for \fI\-std=c++20\fP and \fIstd::experimental::\fP for \fI\-std=c++11\fP\&. .UNINDENT .SS portability\-std\-allocator\-const .sp Report use of \fBstd::vector\fP (and similar containers of const elements). These are not allowed in standard C++, and should usually be \fBstd::vector\fP instead.\(dq .sp Per C++ \fB[allocator.requirements.general]\fP: \(dqT is any cv\-unqualified object type\(dq, \fBstd::allocator\fP is undefined. Many standard containers use \fBstd::allocator\fP by default and therefore their \fBconst T\fP instantiations are undefined. .sp libc++ defines \fBstd::allocator\fP as an extension which will be removed in the future. .sp libstdc++ and MSVC do not support \fBstd::allocator\fP: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // libstdc++ has a better diagnostic since https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48101 std::deque deque; // error: static assertion failed: std::deque must have a non\-const, non\-volatile value_type std::set set; // error: static assertion failed: std::set must have a non\-const, non\-volatile value_type std::vector vector; // error: static assertion failed: std::vector must have a non\-const, non\-volatile value_type // MSVC // error C2338: static_assert failed: \(aqThe C++ Standard forbids containers of const elements because allocator is ill\-formed.\(aq .ft P .fi .UNINDENT .UNINDENT .sp Code bases only compiled with libc++ may accrue such undefined usage. This check finds such code and prevents backsliding while clean\-up is ongoing. .SS readability\-avoid\-const\-params\-in\-decls .sp Checks whether a function declaration has parameters that are top level \fBconst\fP\&. .sp \fBconst\fP values in declarations do not affect the signature of a function, so they should not be put there. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void f(const string); // Bad: const is top level. void f(const string&); // Good: const is not top level. .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreMacros If set to \fItrue\fP, the check will not give warnings inside macros. Default is \fItrue\fP\&. .UNINDENT .SS readability\-avoid\-unconditional\-preprocessor\-if .sp Finds code blocks that are constantly enabled or disabled in preprocessor directives by analyzing \fB#if\fP conditions, such as \fB#if 0\fP and \fB#if 1\fP, etc. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #if 0 // some disabled code #endif #if 1 // some enabled code that can be disabled manually #endif .ft P .fi .UNINDENT .UNINDENT .sp Unconditional preprocessor directives, such as \fB#if 0\fP for disabled code and \fB#if 1\fP for enabled code, can lead to dead code and always enabled code, respectively. Dead code can make understanding the codebase more difficult, hinder readability, and may be a sign of unfinished functionality or abandoned features. This can cause maintenance issues, confusion for future developers, and potential compilation problems. .sp As a solution for both cases, consider using preprocessor macros or defines, like \fB#ifdef DEBUGGING_ENABLED\fP, to control code enabling or disabling. This approach provides better coordination and flexibility when working with different parts of the codebase. Alternatively, you can comment out the entire code using \fB/* */\fP block comments and add a hint, such as \fB@todo\fP, to indicate future actions. .SS readability\-braces\-around\-statements .sp \fIgoogle\-readability\-braces\-around\-statements\fP redirects here as an alias for this check. .sp Checks that bodies of \fBif\fP statements and loops (\fBfor\fP, \fBdo while\fP, and \fBwhile\fP) are inside braces. .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (condition) statement; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if (condition) { statement; } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B ShortStatementLines Defines the minimal number of lines that the statement should have in order to trigger this check. .sp The number of lines is counted from the end of condition or initial keyword (\fBdo\fP/\fBelse\fP) until the last line of the inner statement. Default value \fI0\fP means that braces will be added to all statements (not having them already). .UNINDENT .SS readability\-const\-return\-type .sp Checks for functions with a \fBconst\fP\-qualified return type and recommends removal of the \fBconst\fP keyword. Such use of \fIconst\fP is usually superfluous, and can prevent valuable compiler optimizations. Does not (yet) fix trailing return types. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const int foo(); const Clazz foo(); Clazz *const foo(); .ft P .fi .UNINDENT .UNINDENT .sp Note that this applies strictly to top\-level qualification, which excludes pointers or references to const values. For example, these are fine: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const int* foo(); const int& foo(); const Clazz* foo(); .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B IgnoreMacros If set to \fItrue\fP, the check will not give warnings inside macros. Default is \fItrue\fP\&. .UNINDENT .SS readability\-container\-contains .sp Finds usages of \fBcontainer.count()\fP and \fBcontainer.find() == container.end()\fP which should be replaced by a call to the \fBcontainer.contains()\fP method introduced in C++ 20. .sp Whether an element is contained inside a container should be checked with \fBcontains\fP instead of \fBcount\fP/\fBfind\fP because \fBcontains\fP conveys the intent more clearly. Furthermore, for containers which permit multiple entries per key (\fBmultimap\fP, \fBmultiset\fP, ...), \fBcontains\fP is more efficient than \fBcount\fP because \fBcount\fP has to do unnecessary additional work. .sp Examples: .TS center; |l|l|. _ T{ Initial expression T} T{ Result T} _ T{ \fBmyMap.find(x) == myMap.end()\fP T} T{ \fB!myMap.contains(x)\fP T} _ T{ \fBmyMap.find(x) != myMap.end()\fP T} T{ \fBmyMap.contains(x)\fP T} _ T{ \fBif (myMap.count(x))\fP T} T{ \fBif (myMap.contains(x))\fP T} _ T{ \fBbool exists = myMap.count(x)\fP T} T{ \fBbool exists = myMap.contains(x)\fP T} _ T{ \fBbool exists = myMap.count(x) > 0\fP T} T{ \fBbool exists = myMap.contains(x)\fP T} _ T{ \fBbool exists = myMap.count(x) >= 1\fP T} T{ \fBbool exists = myMap.contains(x)\fP T} _ T{ \fBbool missing = myMap.count(x) == 0\fP T} T{ \fBbool missing = !myMap.contains(x)\fP T} _ .TE .sp This check applies to \fBstd::set\fP, \fBstd::unordered_set\fP, \fBstd::map\fP, \fBstd::unordered_map\fP and the corresponding multi\-key variants. It is only active for C++20 and later, as the \fBcontains\fP method was only added in C++20. .SS readability\-container\-data\-pointer .sp Finds cases where code could use \fBdata()\fP rather than the address of the element at index 0 in a container. This pattern is commonly used to materialize a pointer to the backing data of a container. \fBstd::vector\fP and \fBstd::string\fP provide a \fBdata()\fP accessor to retrieve the data pointer which should be preferred. .sp This also ensures that in the case that the container is empty, the data pointer access does not perform an errant memory access. .SS Options .INDENT 0.0 .TP .B IgnoredContainers Semicolon\-separated list of containers regexp for which this check won\(aqt be enforced. Default is \fIempty\fP\&. .UNINDENT .SS readability\-container\-size\-empty .sp Checks whether a call to the \fBsize()\fP method can be replaced with a call to \fBempty()\fP\&. .sp The emptiness of a container should be checked using the \fBempty()\fP method instead of the \fBsize()\fP method. It is not guaranteed that \fBsize()\fP is a constant\-time function, and it is generally more efficient and also shows clearer intent to use \fBempty()\fP\&. Furthermore some containers may implement the \fBempty()\fP method but not implement the \fBsize()\fP method. Using \fBempty()\fP whenever possible makes it easier to switch to another container in the future. .sp The check issues warning if a container has \fBsize()\fP and \fBempty()\fP methods matching following signatures: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C size_type size() const; bool empty() const; .ft P .fi .UNINDENT .UNINDENT .sp \fIsize_type\fP can be any kind of integer type. .INDENT 0.0 .TP .B ExcludedComparisonTypes A semicolon\-separated list of class names for which the check will ignore comparisons of objects with default\-constructed objects of the same type. If a class is listed here, the check will not suggest using \fBempty()\fP instead of such comparisons for objects of that class. Default value is: \fI::std::array\fP\&. .UNINDENT .SS readability\-convert\-member\-functions\-to\-static .sp Finds non\-static member functions that can be made \fBstatic\fP because the functions don\(aqt use \fBthis\fP\&. .sp After applying modifications as suggested by the check, running the check again might find more opportunities to mark member functions \fBstatic\fP\&. .sp After making a member function \fBstatic\fP, you might want to run the check \fI\%readability\-static\-accessed\-through\-instance\fP to replace calls like \fBInstance.method()\fP by \fBClass::method()\fP\&. .SS readability\-delete\-null\-pointer .sp Checks the \fBif\fP statements where a pointer\(aqs existence is checked and then deletes the pointer. The check is unnecessary as deleting a null pointer has no effect. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int *p; if (p) delete p; .ft P .fi .UNINDENT .UNINDENT .SS readability\-duplicate\-include .sp Looks for duplicate includes and removes them. The check maintains a list of included files and looks for duplicates. If a macro is defined or undefined then the list of included files is cleared. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include #include #include .ft P .fi .UNINDENT .UNINDENT .sp becomes .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #include #include .ft P .fi .UNINDENT .UNINDENT .sp Because of the intervening macro definitions, this code remains unchanged: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #undef NDEBUG #include \(dqassertion.h\(dq // ...code with assertions enabled #define NDEBUG #include \(dqassertion.h\(dq // ...code with assertions disabled .ft P .fi .UNINDENT .UNINDENT .SS readability\-else\-after\-return .sp \fI\%LLVM Coding Standards\fP advises to reduce indentation where possible and where it makes understanding code easier. Early exit is one of the suggested enforcements of that. Please do not use \fBelse\fP or \fBelse if\fP after something that interrupts control flow \- like \fBreturn\fP, \fBbreak\fP, \fBcontinue\fP, \fBthrow\fP\&. .sp The following piece of code illustrates how the check works. This piece of code: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(int Value) { int Local = 0; for (int i = 0; i < 42; i++) { if (Value == 1) { return; } else { Local++; } if (Value == 2) continue; else Local++; if (Value == 3) { throw 42; } else { Local++; } } } .ft P .fi .UNINDENT .UNINDENT .sp Would be transformed into: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo(int Value) { int Local = 0; for (int i = 0; i < 42; i++) { if (Value == 1) { return; } Local++; if (Value == 2) continue; Local++; if (Value == 3) { throw 42; } Local++; } } .ft P .fi .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .TP .B WarnOnUnfixable When \fItrue\fP, emit a warning for cases where the check can\(aqt output a Fix\-It. These can occur with declarations inside the \fBelse\fP branch that would have an extended lifetime if the \fBelse\fP branch was removed. Default value is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B WarnOnConditionVariables When \fItrue\fP, the check will attempt to refactor a variable defined inside the condition of the \fBif\fP statement that is used in the \fBelse\fP branch defining them just before the \fBif\fP statement. This can only be done if the \fBif\fP statement is the last statement in its parent\(aqs scope. Default value is \fItrue\fP\&. .UNINDENT .SS LLVM alias .sp There is an alias of this check called llvm\-else\-after\-return. In that version the options \fI\%WarnOnUnfixable\fP and \fI\%WarnOnConditionVariables\fP are both set to \fIfalse\fP by default. .sp This check helps to enforce this \fI\%LLVM Coding Standards recommendation\fP\&. .SS readability\-function\-cognitive\-complexity .sp Checks function Cognitive Complexity metric. .sp The metric is implemented as per the \fI\%COGNITIVE COMPLEXITY by SonarSource\fP specification version 1.2 (19 April 2017). .SS Options .INDENT 0.0 .TP .B Threshold Flag functions with Cognitive Complexity exceeding this number. The default is \fI25\fP\&. .UNINDENT .INDENT 0.0 .TP .B DescribeBasicIncrements If set to \fItrue\fP, then for each function exceeding the complexity threshold the check will issue additional diagnostics on every piece of code (loop, \fIif\fP statement, etc.) which contributes to that complexity. See also the examples below. Default is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B IgnoreMacros If set to \fItrue\fP, the check will ignore code inside macros. Note, that also any macro arguments are ignored, even if they should count to the complexity. As this might change in the future, this option isn\(aqt guaranteed to be forward\-compatible. Default is \fIfalse\fP\&. .UNINDENT .SS Building blocks .sp There are three basic building blocks of a Cognitive Complexity metric: .SS Increment .sp The following structures increase the function\(aqs Cognitive Complexity metric (by \fI1\fP): .INDENT 0.0 .IP \(bu 2 Conditional operators: .INDENT 2.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBif()\fP .IP \(bu 2 \fBelse if()\fP .IP \(bu 2 \fBelse\fP .IP \(bu 2 \fBcond ? true : false\fP .UNINDENT .UNINDENT .UNINDENT .IP \(bu 2 \fBswitch()\fP .IP \(bu 2 Loops: .INDENT 2.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBfor()\fP .IP \(bu 2 C++11 range\-based \fBfor()\fP .IP \(bu 2 \fBwhile()\fP .IP \(bu 2 \fBdo while()\fP .UNINDENT .UNINDENT .UNINDENT .IP \(bu 2 \fBcatch ()\fP .IP \(bu 2 \fBgoto LABEL\fP, \fBgoto *(&&LABEL))\fP, .IP \(bu 2 sequences of binary logical operators: .INDENT 2.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBboolean1 || boolean2\fP .IP \(bu 2 \fBboolean1 && boolean2\fP .UNINDENT .UNINDENT .UNINDENT .UNINDENT .SS Nesting level .sp While by itself the nesting level does not change the function\(aqs Cognitive Complexity metric, it is tracked, and is used by the next, third building block. The following structures increase the nesting level (by \fI1\fP): .INDENT 0.0 .IP \(bu 2 Conditional operators: .INDENT 2.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBif()\fP .IP \(bu 2 \fBelse if()\fP .IP \(bu 2 \fBelse\fP .IP \(bu 2 \fBcond ? true : false\fP .UNINDENT .UNINDENT .UNINDENT .IP \(bu 2 \fBswitch()\fP .IP \(bu 2 Loops: .INDENT 2.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBfor()\fP .IP \(bu 2 C++11 range\-based \fBfor()\fP .IP \(bu 2 \fBwhile()\fP .IP \(bu 2 \fBdo while()\fP .UNINDENT .UNINDENT .UNINDENT .IP \(bu 2 \fBcatch ()\fP .IP \(bu 2 Nested functions: .INDENT 2.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 C++11 Lambda .IP \(bu 2 Nested \fBclass\fP .IP \(bu 2 Nested \fBstruct\fP .UNINDENT .UNINDENT .UNINDENT .IP \(bu 2 GNU statement expression .IP \(bu 2 Apple Block Declaration .UNINDENT .SS Nesting increment .sp This is where the previous basic building block, \fI\%Nesting level\fP, matters. The following structures increase the function\(aqs Cognitive Complexity metric by the current \fI\%Nesting level\fP: .INDENT 0.0 .IP \(bu 2 Conditional operators: .INDENT 2.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBif()\fP .IP \(bu 2 \fBcond ? true : false\fP .UNINDENT .UNINDENT .UNINDENT .IP \(bu 2 \fBswitch()\fP .IP \(bu 2 Loops: .INDENT 2.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBfor()\fP .IP \(bu 2 C++11 range\-based \fBfor()\fP .IP \(bu 2 \fBwhile()\fP .IP \(bu 2 \fBdo while()\fP .UNINDENT .UNINDENT .UNINDENT .IP \(bu 2 \fBcatch ()\fP .UNINDENT .SS Examples .sp The simplest case. This function has Cognitive Complexity of \fI0\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void function0() {} .ft P .fi .UNINDENT .UNINDENT .sp Slightly better example. This function has Cognitive Complexity of \fI1\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int function1(bool var) { if(var) // +1, nesting level +1 return 42; return 0; } .ft P .fi .UNINDENT .UNINDENT .sp Full example. This function has Cognitive Complexity of \fI3\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int function3(bool var1, bool var2) { if(var1) { // +1, nesting level +1 if(var2) // +2 (1 + current nesting level of 1), nesting level +1 return 42; } return 0; } .ft P .fi .UNINDENT .UNINDENT .sp In the last example, the check will flag \fIfunction3\fP if the option Threshold is set to \fI2\fP or smaller. If the option DescribeBasicIncrements is set to \fItrue\fP, it will additionally flag the two \fIif\fP statements with the amounts by which they increase to the complexity of the function and the current nesting level. .SS Limitations .INDENT 0.0 .TP .B The metric is implemented with two notable exceptions: .INDENT 7.0 .IP \(bu 2 \fIpreprocessor conditionals\fP (\fB#ifdef\fP, \fB#if\fP, \fB#elif\fP, \fB#else\fP, \fB#endif\fP) are not accounted for. .IP \(bu 2 \fIeach method in a recursion cycle\fP is not accounted for. It can\(aqt be fully implemented, because cross\-translational\-unit analysis would be needed, which is currently not possible in clang\-tidy. .UNINDENT .UNINDENT .SS readability\-function\-size .sp \fIgoogle\-readability\-function\-size\fP redirects here as an alias for this check. .sp Checks for large functions based on various metrics. .SS Options .INDENT 0.0 .TP .B LineThreshold Flag functions exceeding this number of lines. The default is \fI\-1\fP (ignore the number of lines). .UNINDENT .INDENT 0.0 .TP .B StatementThreshold Flag functions exceeding this number of statements. This may differ significantly from the number of lines for macro\-heavy code. The default is \fI800\fP\&. .UNINDENT .INDENT 0.0 .TP .B BranchThreshold Flag functions exceeding this number of control statements. The default is \fI\-1\fP (ignore the number of branches). .UNINDENT .INDENT 0.0 .TP .B ParameterThreshold Flag functions that exceed a specified number of parameters. The default is \fI\-1\fP (ignore the number of parameters). .UNINDENT .INDENT 0.0 .TP .B NestingThreshold Flag compound statements which create next nesting level after \fINestingThreshold\fP\&. This may differ significantly from the expected value for macro\-heavy code. The default is \fI\-1\fP (ignore the nesting level). .UNINDENT .INDENT 0.0 .TP .B VariableThreshold Flag functions exceeding this number of variables declared in the body. The default is \fI\-1\fP (ignore the number of variables). Please note that function parameters and variables declared in lambdas, GNU Statement Expressions, and nested class inline functions are not counted. .UNINDENT .SS readability\-identifier\-length .sp This check finds variables and function parameters whose length are too short. The desired name length is configurable. .sp Special cases are supported for loop counters and for exception variable names. .SS Options .sp The following options are described below: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fI\%MinimumVariableNameLength\fP, \fI\%IgnoredVariableNames\fP .IP \(bu 2 \fI\%MinimumParameterNameLength\fP, \fI\%IgnoredParameterNames\fP .IP \(bu 2 \fI\%MinimumLoopCounterNameLength\fP, \fI\%IgnoredLoopCounterNames\fP .IP \(bu 2 \fI\%MinimumExceptionNameLength\fP, \fI\%IgnoredExceptionVariableNames\fP .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B MinimumVariableNameLength All variables (other than loop counter, exception names and function parameters) are expected to have at least a length of \fIMinimumVariableNameLength\fP (default is \fI3\fP). Setting it to \fI0\fP or \fI1\fP disables the check entirely. .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C int doubler(int x) // warns that x is too short { return 2 * x; } .ft P .fi .UNINDENT .UNINDENT .sp This check does not have any fix suggestions in the general case since variable names have semantic value. .UNINDENT .INDENT 0.0 .TP .B IgnoredVariableNames Specifies a regular expression for variable names that are to be ignored. The default value is empty, thus no names are ignored. .UNINDENT .INDENT 0.0 .TP .B MinimumParameterNameLength All function parameter names are expected to have a length of at least \fIMinimumParameterNameLength\fP (default is \fI3\fP). Setting it to \fI0\fP or \fI1\fP disables the check entirely. .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C int i = 42; // warns that \(aqi\(aq is too short .ft P .fi .UNINDENT .UNINDENT .sp This check does not have any fix suggestions in the general case since variable names have semantic value. .UNINDENT .INDENT 0.0 .TP .B IgnoredParameterNames Specifies a regular expression for parameters that are to be ignored. The default value is \fI^[n]$\fP for historical reasons. .UNINDENT .INDENT 0.0 .TP .B MinimumLoopCounterNameLength Loop counter variables are expected to have a length of at least \fIMinimumLoopCounterNameLength\fP characters (default is \fI2\fP). Setting it to \fI0\fP or \fI1\fP disables the check entirely. .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C // This warns that \(aqq\(aq is too short. for (int q = 0; q < size; ++ q) { // ... } .ft P .fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B IgnoredLoopCounterNames Specifies a regular expression for counter names that are to be ignored. The default value is \fI^[ijk_]$\fP; the first three symbols for historical reasons and the last one since it is frequently used as a \(dqdon\(aqt care\(dq value, specifically in tools such as Google Benchmark. .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C // This does not warn by default, for historical reasons. for (int i = 0; i < size; ++ i) { // ... } .ft P .fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B MinimumExceptionNameLength Exception clause variables are expected to have a length of at least \fIMinimumExceptionNameLength\fP (default is \fI2\fP). Setting it to \fI0\fP or \fI1\fP disables the check entirely. .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C try { // ... } // This warns that \(aqe\(aq is too short. catch (const std::exception& x) { // ... } .ft P .fi .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B IgnoredExceptionVariableNames Specifies a regular expression for exception variable names that are to be ignored. The default value is \fI^[e]$\fP mainly for historical reasons. .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C try { // ... } // This does not warn by default, for historical reasons. catch (const std::exception& e) { // ... } .ft P .fi .UNINDENT .UNINDENT .UNINDENT .SS readability\-identifier\-naming .sp Checks for identifiers naming style mismatch. .sp This check will try to enforce coding guidelines on the identifiers naming. It supports one of the following casing types and tries to convert from one to another if a mismatch is detected .sp Casing types include: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBlower_case\fP, .IP \(bu 2 \fBUPPER_CASE\fP, .IP \(bu 2 \fBcamelBack\fP, .IP \(bu 2 \fBCamelCase\fP, .IP \(bu 2 \fBcamel_Snake_Back\fP, .IP \(bu 2 \fBCamel_Snake_Case\fP, .IP \(bu 2 \fBaNy_CasE\fP\&. .UNINDENT .UNINDENT .UNINDENT .sp It also supports a fixed prefix and suffix that will be prepended or appended to the identifiers, regardless of the casing. .sp Many configuration options are available, in order to be able to create different rules for different kinds of identifiers. In general, the rules are falling back to a more generic rule if the specific case is not configured. .sp The naming of virtual methods is reported where they occur in the base class, but not where they are overridden, as it can\(aqt be fixed locally there. This also applies for pseudo\-override patterns like CRTP. .SS Options .sp The following options are described below: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fI\%AbstractClassCase\fP, \fI\%AbstractClassPrefix\fP, \fI\%AbstractClassSuffix\fP, \fI\%AbstractClassIgnoredRegexp\fP, \fI\%AbstractClassHungarianPrefix\fP .IP \(bu 2 \fI\%AggressiveDependentMemberLookup\fP .IP \(bu 2 \fI\%ClassCase\fP, \fI\%ClassPrefix\fP, \fI\%ClassSuffix\fP, \fI\%ClassIgnoredRegexp\fP, \fI\%ClassHungarianPrefix\fP .IP \(bu 2 \fI\%ClassConstantCase\fP, \fI\%ClassConstantPrefix\fP, \fI\%ClassConstantSuffix\fP, \fI\%ClassConstantIgnoredRegexp\fP, \fI\%ClassConstantHungarianPrefix\fP .IP \(bu 2 \fI\%ClassMemberCase\fP, \fI\%ClassMemberPrefix\fP, \fI\%ClassMemberSuffix\fP, \fI\%ClassMemberIgnoredRegexp\fP, \fI\%ClassMemberHungarianPrefix\fP .IP \(bu 2 \fI\%ClassMethodCase\fP, \fI\%ClassMethodPrefix\fP, \fI\%ClassMethodSuffix\fP, \fI\%ClassMethodIgnoredRegexp\fP .IP \(bu 2 \fI\%ConstantCase\fP, \fI\%ConstantPrefix\fP, \fI\%ConstantSuffix\fP, \fI\%ConstantIgnoredRegexp\fP, \fI\%ConstantHungarianPrefix\fP .IP \(bu 2 \fI\%ConstantMemberCase\fP, \fI\%ConstantMemberPrefix\fP, \fI\%ConstantMemberSuffix\fP, \fI\%ConstantMemberIgnoredRegexp\fP, \fI\%ConstantMemberHungarianPrefix\fP .IP \(bu 2 \fI\%ConstantParameterCase\fP, \fI\%ConstantParameterPrefix\fP, \fI\%ConstantParameterSuffix\fP, \fI\%ConstantParameterIgnoredRegexp\fP, \fI\%ConstantParameterHungarianPrefix\fP .IP \(bu 2 \fI\%ConstantPointerParameterCase\fP, \fI\%ConstantPointerParameterPrefix\fP, \fI\%ConstantPointerParameterSuffix\fP, \fI\%ConstantPointerParameterIgnoredRegexp\fP, \fI\%ConstantPointerParameterHungarianPrefix\fP .IP \(bu 2 \fI\%ConstexprFunctionCase\fP, \fI\%ConstexprFunctionPrefix\fP, \fI\%ConstexprFunctionSuffix\fP, \fI\%ConstexprFunctionIgnoredRegexp\fP .IP \(bu 2 \fI\%ConstexprMethodCase\fP, \fI\%ConstexprMethodPrefix\fP, \fI\%ConstexprMethodSuffix\fP, \fI\%ConstexprMethodIgnoredRegexp\fP .IP \(bu 2 \fI\%ConstexprVariableCase\fP, \fI\%ConstexprVariablePrefix\fP, \fI\%ConstexprVariableSuffix\fP, \fI\%ConstexprVariableIgnoredRegexp\fP, \fI\%ConstexprVariableHungarianPrefix\fP .IP \(bu 2 \fI\%EnumCase\fP, \fI\%EnumPrefix\fP, \fI\%EnumSuffix\fP, \fI\%EnumIgnoredRegexp\fP .IP \(bu 2 \fI\%EnumConstantCase\fP, \fI\%EnumConstantPrefix\fP, \fI\%EnumConstantSuffix\fP, \fI\%EnumConstantIgnoredRegexp\fP, \fI\%EnumConstantHungarianPrefix\fP .IP \(bu 2 \fI\%FunctionCase\fP, \fI\%FunctionPrefix\fP, \fI\%FunctionSuffix\fP, \fI\%FunctionIgnoredRegexp\fP .IP \(bu 2 \fI\%GetConfigPerFile\fP .IP \(bu 2 \fI\%GlobalConstantCase\fP, \fI\%GlobalConstantPrefix\fP, \fI\%GlobalConstantSuffix\fP, \fI\%GlobalConstantIgnoredRegexp\fP, \fI\%GlobalConstantHungarianPrefix\fP .IP \(bu 2 \fI\%GlobalConstantPointerCase\fP, \fI\%GlobalConstantPointerPrefix\fP, \fI\%GlobalConstantPointerSuffix\fP, \fI\%GlobalConstantPointerIgnoredRegexp\fP, \fI\%GlobalConstantPointerHungarianPrefix\fP .IP \(bu 2 \fI\%GlobalFunctionCase\fP, \fI\%GlobalFunctionPrefix\fP, \fI\%GlobalFunctionSuffix\fP, \fI\%GlobalFunctionIgnoredRegexp\fP .IP \(bu 2 \fI\%GlobalPointerCase\fP, \fI\%GlobalPointerPrefix\fP, \fI\%GlobalPointerSuffix\fP, \fI\%GlobalPointerIgnoredRegexp\fP, \fI\%GlobalPointerHungarianPrefix\fP .IP \(bu 2 \fI\%GlobalVariableCase\fP, \fI\%GlobalVariablePrefix\fP, \fI\%GlobalVariableSuffix\fP, \fI\%GlobalVariableIgnoredRegexp\fP, \fI\%GlobalVariableHungarianPrefix\fP .IP \(bu 2 \fI\%IgnoreMainLikeFunctions\fP .IP \(bu 2 \fI\%InlineNamespaceCase\fP, \fI\%InlineNamespacePrefix\fP, \fI\%InlineNamespaceSuffix\fP, \fI\%InlineNamespaceIgnoredRegexp\fP .IP \(bu 2 \fI\%LocalConstantCase\fP, \fI\%LocalConstantPrefix\fP, \fI\%LocalConstantSuffix\fP, \fI\%LocalConstantIgnoredRegexp\fP, \fI\%LocalConstantHungarianPrefix\fP .IP \(bu 2 \fI\%LocalConstantPointerCase\fP, \fI\%LocalConstantPointerPrefix\fP, \fI\%LocalConstantPointerSuffix\fP, \fI\%LocalConstantPointerIgnoredRegexp\fP, \fI\%LocalConstantPointerHungarianPrefix\fP .IP \(bu 2 \fI\%LocalPointerCase\fP, \fI\%LocalPointerPrefix\fP, \fI\%LocalPointerSuffix\fP, \fI\%LocalPointerIgnoredRegexp\fP, \fI\%LocalPointerHungarianPrefix\fP .IP \(bu 2 \fI\%LocalVariableCase\fP, \fI\%LocalVariablePrefix\fP, \fI\%LocalVariableSuffix\fP, \fI\%LocalVariableIgnoredRegexp\fP, \fI\%LocalVariableHungarianPrefix\fP .IP \(bu 2 \fI\%MacroDefinitionCase\fP, \fI\%MacroDefinitionPrefix\fP, \fI\%MacroDefinitionSuffix\fP, \fI\%MacroDefinitionIgnoredRegexp\fP .IP \(bu 2 \fI\%MemberCase\fP, \fI\%MemberPrefix\fP, \fI\%MemberSuffix\fP, \fI\%MemberIgnoredRegexp\fP, \fI\%MemberHungarianPrefix\fP .IP \(bu 2 \fI\%MethodCase\fP, \fI\%MethodPrefix\fP, \fI\%MethodSuffix\fP, \fI\%MethodIgnoredRegexp\fP .IP \(bu 2 \fI\%NamespaceCase\fP, \fI\%NamespacePrefix\fP, \fI\%NamespaceSuffix\fP, \fI\%NamespaceIgnoredRegexp\fP .IP \(bu 2 \fI\%ParameterCase\fP, \fI\%ParameterPrefix\fP, \fI\%ParameterSuffix\fP, \fI\%ParameterIgnoredRegexp\fP, \fI\%ParameterHungarianPrefix\fP .IP \(bu 2 \fI\%ParameterPackCase\fP, \fI\%ParameterPackPrefix\fP, \fI\%ParameterPackSuffix\fP, \fI\%ParameterPackIgnoredRegexp\fP .IP \(bu 2 \fI\%PointerParameterCase\fP, \fI\%PointerParameterPrefix\fP, \fI\%PointerParameterSuffix\fP, \fI\%PointerParameterIgnoredRegexp\fP, \fI\%PointerParameterHungarianPrefix\fP .IP \(bu 2 \fI\%PrivateMemberCase\fP, \fI\%PrivateMemberPrefix\fP, \fI\%PrivateMemberSuffix\fP, \fI\%PrivateMemberIgnoredRegexp\fP, \fI\%PrivateMemberHungarianPrefix\fP .IP \(bu 2 \fI\%PrivateMethodCase\fP, \fI\%PrivateMethodPrefix\fP, \fI\%PrivateMethodSuffix\fP, \fI\%PrivateMethodIgnoredRegexp\fP .IP \(bu 2 \fI\%ProtectedMemberCase\fP, \fI\%ProtectedMemberPrefix\fP, \fI\%ProtectedMemberSuffix\fP, \fI\%ProtectedMemberIgnoredRegexp\fP, \fI\%ProtectedMemberHungarianPrefix\fP .IP \(bu 2 \fI\%ProtectedMethodCase\fP, \fI\%ProtectedMethodPrefix\fP, \fI\%ProtectedMethodSuffix\fP, \fI\%ProtectedMethodIgnoredRegexp\fP .IP \(bu 2 \fI\%PublicMemberCase\fP, \fI\%PublicMemberPrefix\fP, \fI\%PublicMemberSuffix\fP, \fI\%PublicMemberIgnoredRegexp\fP, \fI\%PublicMemberHungarianPrefix\fP .IP \(bu 2 \fI\%PublicMethodCase\fP, \fI\%PublicMethodPrefix\fP, \fI\%PublicMethodSuffix\fP, \fI\%PublicMethodIgnoredRegexp\fP .IP \(bu 2 \fI\%ScopedEnumConstantCase\fP, \fI\%ScopedEnumConstantPrefix\fP, \fI\%ScopedEnumConstantSuffix\fP, \fI\%ScopedEnumConstantIgnoredRegexp\fP .IP \(bu 2 \fI\%StaticConstantCase\fP, \fI\%StaticConstantPrefix\fP, \fI\%StaticConstantSuffix\fP, \fI\%StaticConstantIgnoredRegexp\fP, \fI\%StaticConstantHungarianPrefix\fP .IP \(bu 2 \fI\%StaticVariableCase\fP, \fI\%StaticVariablePrefix\fP, \fI\%StaticVariableSuffix\fP, \fI\%StaticVariableIgnoredRegexp\fP, \fI\%StaticVariableHungarianPrefix\fP .IP \(bu 2 \fI\%StructCase\fP, \fI\%StructPrefix\fP, \fI\%StructSuffix\fP, \fI\%StructIgnoredRegexp\fP .IP \(bu 2 \fI\%TemplateParameterCase\fP, \fI\%TemplateParameterPrefix\fP, \fI\%TemplateParameterSuffix\fP, \fI\%TemplateParameterIgnoredRegexp\fP .IP \(bu 2 \fI\%TemplateTemplateParameterCase\fP, \fI\%TemplateTemplateParameterPrefix\fP, \fI\%TemplateTemplateParameterSuffix\fP, \fI\%TemplateTemplateParameterIgnoredRegexp\fP .IP \(bu 2 \fI\%TypeAliasCase\fP, \fI\%TypeAliasPrefix\fP, \fI\%TypeAliasSuffix\fP, \fI\%TypeAliasIgnoredRegexp\fP .IP \(bu 2 \fI\%TypedefCase\fP, \fI\%TypedefPrefix\fP, \fI\%TypedefSuffix\fP, \fI\%TypedefIgnoredRegexp\fP .IP \(bu 2 \fI\%TypeTemplateParameterCase\fP, \fI\%TypeTemplateParameterPrefix\fP, \fI\%TypeTemplateParameterSuffix\fP, \fI\%TypeTemplateParameterIgnoredRegexp\fP .IP \(bu 2 \fI\%UnionCase\fP, \fI\%UnionPrefix\fP, \fI\%UnionSuffix\fP, \fI\%UnionIgnoredRegexp\fP .IP \(bu 2 \fI\%ValueTemplateParameterCase\fP, \fI\%ValueTemplateParameterPrefix\fP, \fI\%ValueTemplateParameterSuffix\fP, \fI\%ValueTemplateParameterIgnoredRegexp\fP .IP \(bu 2 \fI\%VariableCase\fP, \fI\%VariablePrefix\fP, \fI\%VariableSuffix\fP, \fI\%VariableIgnoredRegexp\fP, \fI\%VariableHungarianPrefix\fP .IP \(bu 2 \fI\%VirtualMethodCase\fP, \fI\%VirtualMethodPrefix\fP, \fI\%VirtualMethodSuffix\fP, \fI\%VirtualMethodIgnoredRegexp\fP .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .TP .B AbstractClassCase When defined, the check will ensure abstract class names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B AbstractClassPrefix When defined, the check will ensure abstract class names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B AbstractClassIgnoredRegexp Identifier naming checks won\(aqt be enforced for abstract class names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B AbstractClassSuffix When defined, the check will ensure abstract class names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B AbstractClassHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 AbstractClassCase of \fBlower_case\fP .IP \(bu 2 AbstractClassPrefix of \fBpre_\fP .IP \(bu 2 AbstractClassSuffix of \fB_post\fP .IP \(bu 2 AbstractClassHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms abstract class names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class ABSTRACT_CLASS { public: ABSTRACT_CLASS(); }; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class pre_abstract_class_post { public: pre_abstract_class_post(); }; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B AggressiveDependentMemberLookup When set to \fItrue\fP the check will look in dependent base classes for dependent member references that need changing. This can lead to errors with template specializations so the default value is \fIfalse\fP\&. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ClassMemberCase of \fBlower_case\fP .UNINDENT .UNINDENT .UNINDENT .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C template struct Base { T BadNamedMember; }; template struct Derived : Base { void reset() { this\->BadNamedMember = 0; } }; .ft P .fi .UNINDENT .UNINDENT .sp After if AggressiveDependentMemberLookup is \fIfalse\fP: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C template struct Base { T bad_named_member; }; template struct Derived : Base { void reset() { this\->BadNamedMember = 0; } }; .ft P .fi .UNINDENT .UNINDENT .sp After if AggressiveDependentMemberLookup is \fItrue\fP: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C template struct Base { T bad_named_member; }; template struct Derived : Base { void reset() { this\->bad_named_member = 0; } }; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ClassCase When defined, the check will ensure class names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ClassPrefix When defined, the check will ensure class names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ClassIgnoredRegexp Identifier naming checks won\(aqt be enforced for class names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ClassSuffix When defined, the check will ensure class names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ClassHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ClassCase of \fBlower_case\fP .IP \(bu 2 ClassPrefix of \fBpre_\fP .IP \(bu 2 ClassSuffix of \fB_post\fP .IP \(bu 2 ClassHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms class names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class FOO { public: FOO(); ~FOO(); }; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class pre_foo_post { public: pre_foo_post(); ~pre_foo_post(); }; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ClassConstantCase When defined, the check will ensure class constant names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ClassConstantPrefix When defined, the check will ensure class constant names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ClassConstantIgnoredRegexp Identifier naming checks won\(aqt be enforced for class constant names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ClassConstantSuffix When defined, the check will ensure class constant names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ClassConstantHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ClassConstantCase of \fBlower_case\fP .IP \(bu 2 ClassConstantPrefix of \fBpre_\fP .IP \(bu 2 ClassConstantSuffix of \fB_post\fP .IP \(bu 2 ClassConstantHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms class constant names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class FOO { public: static const int CLASS_CONSTANT; }; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class FOO { public: static const int pre_class_constant_post; }; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ClassMemberCase When defined, the check will ensure class member names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ClassMemberPrefix When defined, the check will ensure class member names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ClassMemberIgnoredRegexp Identifier naming checks won\(aqt be enforced for class member names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ClassMemberSuffix When defined, the check will ensure class member names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ClassMemberHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ClassMemberCase of \fBlower_case\fP .IP \(bu 2 ClassMemberPrefix of \fBpre_\fP .IP \(bu 2 ClassMemberSuffix of \fB_post\fP .IP \(bu 2 ClassMemberHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms class member names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class FOO { public: static int CLASS_CONSTANT; }; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class FOO { public: static int pre_class_constant_post; }; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ClassMethodCase When defined, the check will ensure class method names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ClassMethodPrefix When defined, the check will ensure class method names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ClassMethodIgnoredRegexp Identifier naming checks won\(aqt be enforced for class method names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ClassMethodSuffix When defined, the check will ensure class method names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ClassMethodCase of \fBlower_case\fP .IP \(bu 2 ClassMethodPrefix of \fBpre_\fP .IP \(bu 2 ClassMethodSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms class method names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class FOO { public: int CLASS_MEMBER(); }; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class FOO { public: int pre_class_member_post(); }; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ConstantCase When defined, the check will ensure constant names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ConstantPrefix When defined, the check will ensure constant names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ConstantIgnoredRegexp Identifier naming checks won\(aqt be enforced for constant names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ConstantSuffix When defined, the check will ensure constant names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ConstantHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ConstantCase of \fBlower_case\fP .IP \(bu 2 ConstantPrefix of \fBpre_\fP .IP \(bu 2 ConstantSuffix of \fB_post\fP .IP \(bu 2 ConstantHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms constant names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void function() { unsigned const MyConst_array[] = {1, 2, 3}; } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void function() { unsigned const pre_myconst_array_post[] = {1, 2, 3}; } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ConstantMemberCase When defined, the check will ensure constant member names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ConstantMemberPrefix When defined, the check will ensure constant member names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ConstantMemberIgnoredRegexp Identifier naming checks won\(aqt be enforced for constant member names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ConstantMemberSuffix When defined, the check will ensure constant member names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ConstantMemberHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ConstantMemberCase of \fBlower_case\fP .IP \(bu 2 ConstantMemberPrefix of \fBpre_\fP .IP \(bu 2 ConstantMemberSuffix of \fB_post\fP .IP \(bu 2 ConstantMemberHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms constant member names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { char const MY_ConstMember_string[4] = \(dq123\(dq; } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { char const pre_my_constmember_string_post[4] = \(dq123\(dq; } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ConstantParameterCase When defined, the check will ensure constant parameter names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ConstantParameterPrefix When defined, the check will ensure constant parameter names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ConstantParameterIgnoredRegexp Identifier naming checks won\(aqt be enforced for constant parameter names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ConstantParameterSuffix When defined, the check will ensure constant parameter names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ConstantParameterHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ConstantParameterCase of \fBlower_case\fP .IP \(bu 2 ConstantParameterPrefix of \fBpre_\fP .IP \(bu 2 ConstantParameterSuffix of \fB_post\fP .IP \(bu 2 ConstantParameterHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms constant parameter names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void GLOBAL_FUNCTION(int PARAMETER_1, int const CONST_parameter); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void GLOBAL_FUNCTION(int PARAMETER_1, int const pre_const_parameter_post); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ConstantPointerParameterCase When defined, the check will ensure constant pointer parameter names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ConstantPointerParameterPrefix When defined, the check will ensure constant pointer parameter names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ConstantPointerParameterIgnoredRegexp Identifier naming checks won\(aqt be enforced for constant pointer parameter names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ConstantPointerParameterSuffix When defined, the check will ensure constant pointer parameter names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ConstantPointerParameterHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ConstantPointerParameterCase of \fBlower_case\fP .IP \(bu 2 ConstantPointerParameterPrefix of \fBpre_\fP .IP \(bu 2 ConstantPointerParameterSuffix of \fB_post\fP .IP \(bu 2 ConstantPointerParameterHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms constant pointer parameter names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void GLOBAL_FUNCTION(int const *CONST_parameter); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void GLOBAL_FUNCTION(int const *pre_const_parameter_post); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ConstexprFunctionCase When defined, the check will ensure constexpr function names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ConstexprFunctionPrefix When defined, the check will ensure constexpr function names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ConstexprFunctionIgnoredRegexp Identifier naming checks won\(aqt be enforced for constexpr function names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ConstexprFunctionSuffix When defined, the check will ensure constexpr function names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ConstexprFunctionCase of \fBlower_case\fP .IP \(bu 2 ConstexprFunctionPrefix of \fBpre_\fP .IP \(bu 2 ConstexprFunctionSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms constexpr function names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C constexpr int CE_function() { return 3; } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C constexpr int pre_ce_function_post() { return 3; } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ConstexprMethodCase When defined, the check will ensure constexpr method names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ConstexprMethodPrefix When defined, the check will ensure constexpr method names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ConstexprMethodIgnoredRegexp Identifier naming checks won\(aqt be enforced for constexpr method names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ConstexprMethodSuffix When defined, the check will ensure constexpr method names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ConstexprMethodCase of \fBlower_case\fP .IP \(bu 2 ConstexprMethodPrefix of \fBpre_\fP .IP \(bu 2 ConstexprMethodSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms constexpr method names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { public: constexpr int CST_expr_Method() { return 2; } } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { public: constexpr int pre_cst_expr_method_post() { return 2; } } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ConstexprVariableCase When defined, the check will ensure constexpr variable names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ConstexprVariablePrefix When defined, the check will ensure constexpr variable names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ConstexprVariableIgnoredRegexp Identifier naming checks won\(aqt be enforced for constexpr variable names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ConstexprVariableSuffix When defined, the check will ensure constexpr variable names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ConstexprVariableHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ConstexprVariableCase of \fBlower_case\fP .IP \(bu 2 ConstexprVariablePrefix of \fBpre_\fP .IP \(bu 2 ConstexprVariableSuffix of \fB_post\fP .IP \(bu 2 ConstexprVariableHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms constexpr variable names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C constexpr int ConstExpr_variable = MyConstant; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C constexpr int pre_constexpr_variable_post = MyConstant; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B EnumCase When defined, the check will ensure enumeration names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B EnumPrefix When defined, the check will ensure enumeration names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B EnumIgnoredRegexp Identifier naming checks won\(aqt be enforced for enumeration names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B EnumSuffix When defined, the check will ensure enumeration names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 EnumCase of \fBlower_case\fP .IP \(bu 2 EnumPrefix of \fBpre_\fP .IP \(bu 2 EnumSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms enumeration names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C enum FOO { One, Two, Three }; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C enum pre_foo_post { One, Two, Three }; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B EnumConstantCase When defined, the check will ensure enumeration constant names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B EnumConstantPrefix When defined, the check will ensure enumeration constant names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B EnumConstantIgnoredRegexp Identifier naming checks won\(aqt be enforced for enumeration constant names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B EnumConstantSuffix When defined, the check will ensure enumeration constant names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B EnumConstantHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 EnumConstantCase of \fBlower_case\fP .IP \(bu 2 EnumConstantPrefix of \fBpre_\fP .IP \(bu 2 EnumConstantSuffix of \fB_post\fP .IP \(bu 2 EnumConstantHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms enumeration constant names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C enum FOO { One, Two, Three }; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C enum FOO { pre_One_post, pre_Two_post, pre_Three_post }; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B FunctionCase When defined, the check will ensure function names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B FunctionPrefix When defined, the check will ensure function names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B FunctionIgnoredRegexp Identifier naming checks won\(aqt be enforced for function names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B FunctionSuffix When defined, the check will ensure function names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 FunctionCase of \fBlower_case\fP .IP \(bu 2 FunctionPrefix of \fBpre_\fP .IP \(bu 2 FunctionSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms function names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C char MY_Function_string(); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C char pre_my_function_string_post(); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B GetConfigPerFile When \fItrue\fP the check will look for the configuration for where an identifier is declared. Useful for when included header files use a different style. Default value is \fItrue\fP\&. .UNINDENT .INDENT 0.0 .TP .B GlobalConstantCase When defined, the check will ensure global constant names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B GlobalConstantPrefix When defined, the check will ensure global constant names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B GlobalConstantIgnoredRegexp Identifier naming checks won\(aqt be enforced for global constant names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B GlobalConstantSuffix When defined, the check will ensure global constant names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B GlobalConstantHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 GlobalConstantCase of \fBlower_case\fP .IP \(bu 2 GlobalConstantPrefix of \fBpre_\fP .IP \(bu 2 GlobalConstantSuffix of \fB_post\fP .IP \(bu 2 GlobalConstantHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms global constant names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C unsigned const MyConstGlobal_array[] = {1, 2, 3}; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C unsigned const pre_myconstglobal_array_post[] = {1, 2, 3}; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B GlobalConstantPointerCase When defined, the check will ensure global constant pointer names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B GlobalConstantPointerPrefix When defined, the check will ensure global constant pointer names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B GlobalConstantPointerIgnoredRegexp Identifier naming checks won\(aqt be enforced for global constant pointer names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B GlobalConstantPointerSuffix When defined, the check will ensure global constant pointer names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B GlobalConstantPointerHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 GlobalConstantPointerCase of \fBlower_case\fP .IP \(bu 2 GlobalConstantPointerPrefix of \fBpre_\fP .IP \(bu 2 GlobalConstantPointerSuffix of \fB_post\fP .IP \(bu 2 GlobalConstantPointerHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms global constant pointer names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int *const MyConstantGlobalPointer = nullptr; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int *const pre_myconstantglobalpointer_post = nullptr; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B GlobalFunctionCase When defined, the check will ensure global function names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B GlobalFunctionPrefix When defined, the check will ensure global function names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B GlobalFunctionIgnoredRegexp Identifier naming checks won\(aqt be enforced for global function names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B GlobalFunctionSuffix When defined, the check will ensure global function names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 GlobalFunctionCase of \fBlower_case\fP .IP \(bu 2 GlobalFunctionPrefix of \fBpre_\fP .IP \(bu 2 GlobalFunctionSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms global function names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void GLOBAL_FUNCTION(int PARAMETER_1, int const CONST_parameter); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void pre_global_function_post(int PARAMETER_1, int const CONST_parameter); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B GlobalPointerCase When defined, the check will ensure global pointer names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B GlobalPointerPrefix When defined, the check will ensure global pointer names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B GlobalPointerIgnoredRegexp Identifier naming checks won\(aqt be enforced for global pointer names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B GlobalPointerSuffix When defined, the check will ensure global pointer names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B GlobalPointerHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 GlobalPointerCase of \fBlower_case\fP .IP \(bu 2 GlobalPointerPrefix of \fBpre_\fP .IP \(bu 2 GlobalPointerSuffix of \fB_post\fP .IP \(bu 2 GlobalPointerHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms global pointer names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int *GLOBAL3; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int *pre_global3_post; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B GlobalVariableCase When defined, the check will ensure global variable names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B GlobalVariablePrefix When defined, the check will ensure global variable names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B GlobalVariableIgnoredRegexp Identifier naming checks won\(aqt be enforced for global variable names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B GlobalVariableSuffix When defined, the check will ensure global variable names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B GlobalVariableHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 GlobalVariableCase of \fBlower_case\fP .IP \(bu 2 GlobalVariablePrefix of \fBpre_\fP .IP \(bu 2 GlobalVariableSuffix of \fB_post\fP .IP \(bu 2 GlobalVariableHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms global variable names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int GLOBAL3; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C int pre_global3_post; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B IgnoreMainLikeFunctions When set to \fItrue\fP functions that have a similar signature to \fBmain\fP or \fBwmain\fP won\(aqt enforce checks on the names of their parameters. Default value is \fIfalse\fP\&. .UNINDENT .INDENT 0.0 .TP .B InlineNamespaceCase When defined, the check will ensure inline namespaces names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B InlineNamespacePrefix When defined, the check will ensure inline namespaces names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B InlineNamespaceIgnoredRegexp Identifier naming checks won\(aqt be enforced for inline namespaces names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B InlineNamespaceSuffix When defined, the check will ensure inline namespaces names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 InlineNamespaceCase of \fBlower_case\fP .IP \(bu 2 InlineNamespacePrefix of \fBpre_\fP .IP \(bu 2 InlineNamespaceSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms inline namespaces names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C namespace FOO_NS { inline namespace InlineNamespace { \&... } } // namespace FOO_NS .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C namespace FOO_NS { inline namespace pre_inlinenamespace_post { \&... } } // namespace FOO_NS .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B LocalConstantCase When defined, the check will ensure local constant names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B LocalConstantPrefix When defined, the check will ensure local constant names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B LocalConstantIgnoredRegexp Identifier naming checks won\(aqt be enforced for local constant names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B LocalConstantSuffix When defined, the check will ensure local constant names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B LocalConstantHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 LocalConstantCase of \fBlower_case\fP .IP \(bu 2 LocalConstantPrefix of \fBpre_\fP .IP \(bu 2 LocalConstantSuffix of \fB_post\fP .IP \(bu 2 LocalConstantHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms local constant names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo() { int const local_Constant = 3; } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo() { int const pre_local_constant_post = 3; } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B LocalConstantPointerCase When defined, the check will ensure local constant pointer names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B LocalConstantPointerPrefix When defined, the check will ensure local constant pointer names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B LocalConstantPointerIgnoredRegexp Identifier naming checks won\(aqt be enforced for local constant pointer names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B LocalConstantPointerSuffix When defined, the check will ensure local constant pointer names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B LocalConstantPointerHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 LocalConstantPointerCase of \fBlower_case\fP .IP \(bu 2 LocalConstantPointerPrefix of \fBpre_\fP .IP \(bu 2 LocalConstantPointerSuffix of \fB_post\fP .IP \(bu 2 LocalConstantPointerHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms local constant pointer names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo() { int const *local_Constant = 3; } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo() { int const *pre_local_constant_post = 3; } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B LocalPointerCase When defined, the check will ensure local pointer names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B LocalPointerPrefix When defined, the check will ensure local pointer names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B LocalPointerIgnoredRegexp Identifier naming checks won\(aqt be enforced for local pointer names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B LocalPointerSuffix When defined, the check will ensure local pointer names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B LocalPointerHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 LocalPointerCase of \fBlower_case\fP .IP \(bu 2 LocalPointerPrefix of \fBpre_\fP .IP \(bu 2 LocalPointerSuffix of \fB_post\fP .IP \(bu 2 LocalPointerHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms local pointer names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo() { int *local_Constant; } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo() { int *pre_local_constant_post; } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B LocalVariableCase When defined, the check will ensure local variable names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B LocalVariablePrefix When defined, the check will ensure local variable names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B LocalVariableIgnoredRegexp Identifier naming checks won\(aqt be enforced for local variable names matching this regular expression. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 LocalVariableCase of \fBCamelCase\fP .IP \(bu 2 LocalVariableIgnoredRegexp of \fB\ew{1,2}\fP .UNINDENT .UNINDENT .UNINDENT .sp Will exclude variables with a length less than or equal to 2 from the camel case check applied to other variables. .INDENT 0.0 .TP .B LocalVariableSuffix When defined, the check will ensure local variable names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B LocalVariableHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 LocalVariableCase of \fBlower_case\fP .IP \(bu 2 LocalVariablePrefix of \fBpre_\fP .IP \(bu 2 LocalVariableSuffix of \fB_post\fP .IP \(bu 2 LocalVariableHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms local variable names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo() { int local_Constant; } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void foo() { int pre_local_constant_post; } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B MacroDefinitionCase When defined, the check will ensure macro definitions conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B MacroDefinitionPrefix When defined, the check will ensure macro definitions will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B MacroDefinitionIgnoredRegexp Identifier naming checks won\(aqt be enforced for macro definitions matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B MacroDefinitionSuffix When defined, the check will ensure macro definitions will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 MacroDefinitionCase of \fBlower_case\fP .IP \(bu 2 MacroDefinitionPrefix of \fBpre_\fP .IP \(bu 2 MacroDefinitionSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms macro definitions as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #define MY_MacroDefinition .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C #define pre_my_macro_definition_post .ft P .fi .UNINDENT .UNINDENT .sp Note: This will not warn on builtin macros or macros defined on the command line using the \fB\-D\fP flag. .INDENT 0.0 .TP .B MemberCase When defined, the check will ensure member names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B MemberPrefix When defined, the check will ensure member names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B MemberIgnoredRegexp Identifier naming checks won\(aqt be enforced for member names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B MemberSuffix When defined, the check will ensure member names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B MemberHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 MemberCase of \fBlower_case\fP .IP \(bu 2 MemberPrefix of \fBpre_\fP .IP \(bu 2 MemberSuffix of \fB_post\fP .IP \(bu 2 MemberHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms member names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { char MY_ConstMember_string[4]; } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { char pre_my_constmember_string_post[4]; } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B MethodCase When defined, the check will ensure method names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B MethodPrefix When defined, the check will ensure method names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B MethodIgnoredRegexp Identifier naming checks won\(aqt be enforced for method names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B MethodSuffix When defined, the check will ensure method names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 MethodCase of \fBlower_case\fP .IP \(bu 2 MethodPrefix of \fBpre_\fP .IP \(bu 2 MethodSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms method names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { char MY_Method_string(); } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { char pre_my_method_string_post(); } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B NamespaceCase When defined, the check will ensure namespace names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B NamespacePrefix When defined, the check will ensure namespace names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B NamespaceIgnoredRegexp Identifier naming checks won\(aqt be enforced for namespace names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B NamespaceSuffix When defined, the check will ensure namespace names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 NamespaceCase of \fBlower_case\fP .IP \(bu 2 NamespacePrefix of \fBpre_\fP .IP \(bu 2 NamespaceSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms namespace names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C namespace FOO_NS { \&... } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C namespace pre_foo_ns_post { \&... } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ParameterCase When defined, the check will ensure parameter names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ParameterPrefix When defined, the check will ensure parameter names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ParameterIgnoredRegexp Identifier naming checks won\(aqt be enforced for parameter names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ParameterSuffix When defined, the check will ensure parameter names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ParameterHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ParameterCase of \fBlower_case\fP .IP \(bu 2 ParameterPrefix of \fBpre_\fP .IP \(bu 2 ParameterSuffix of \fB_post\fP .IP \(bu 2 ParameterHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms parameter names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void GLOBAL_FUNCTION(int PARAMETER_1, int const CONST_parameter); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void GLOBAL_FUNCTION(int pre_parameter_post, int const CONST_parameter); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ParameterPackCase When defined, the check will ensure parameter pack names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ParameterPackPrefix When defined, the check will ensure parameter pack names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ParameterPackIgnoredRegexp Identifier naming checks won\(aqt be enforced for parameter pack names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ParameterPackSuffix When defined, the check will ensure parameter pack names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ParameterPackCase of \fBlower_case\fP .IP \(bu 2 ParameterPackPrefix of \fBpre_\fP .IP \(bu 2 ParameterPackSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms parameter pack names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C template { void FUNCTION(int... TYPE_parameters); } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C template { void FUNCTION(int... pre_type_parameters_post); } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B PointerParameterCase When defined, the check will ensure pointer parameter names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B PointerParameterPrefix When defined, the check will ensure pointer parameter names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B PointerParameterIgnoredRegexp Identifier naming checks won\(aqt be enforced for pointer parameter names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B PointerParameterSuffix When defined, the check will ensure pointer parameter names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B PointerParameterHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 PointerParameterCase of \fBlower_case\fP .IP \(bu 2 PointerParameterPrefix of \fBpre_\fP .IP \(bu 2 PointerParameterSuffix of \fB_post\fP .IP \(bu 2 PointerParameterHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms pointer parameter names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void FUNCTION(int *PARAMETER); .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C void FUNCTION(int *pre_parameter_post); .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B PrivateMemberCase When defined, the check will ensure private member names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B PrivateMemberPrefix When defined, the check will ensure private member names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B PrivateMemberIgnoredRegexp Identifier naming checks won\(aqt be enforced for private member names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B PrivateMemberSuffix When defined, the check will ensure private member names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B PrivateMemberHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 PrivateMemberCase of \fBlower_case\fP .IP \(bu 2 PrivateMemberPrefix of \fBpre_\fP .IP \(bu 2 PrivateMemberSuffix of \fB_post\fP .IP \(bu 2 PrivateMemberHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms private member names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { private: int Member_Variable; } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { private: int pre_member_variable_post; } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B PrivateMethodCase When defined, the check will ensure private method names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B PrivateMethodPrefix When defined, the check will ensure private method names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B PrivateMethodIgnoredRegexp Identifier naming checks won\(aqt be enforced for private method names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B PrivateMethodSuffix When defined, the check will ensure private method names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 PrivateMethodCase of \fBlower_case\fP .IP \(bu 2 PrivateMethodPrefix of \fBpre_\fP .IP \(bu 2 PrivateMethodSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms private method names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { private: int Member_Method(); } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { private: int pre_member_method_post(); } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ProtectedMemberCase When defined, the check will ensure protected member names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ProtectedMemberPrefix When defined, the check will ensure protected member names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ProtectedMemberIgnoredRegexp Identifier naming checks won\(aqt be enforced for protected member names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ProtectedMemberSuffix When defined, the check will ensure protected member names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ProtectedMemberHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ProtectedMemberCase of \fBlower_case\fP .IP \(bu 2 ProtectedMemberPrefix of \fBpre_\fP .IP \(bu 2 ProtectedMemberSuffix of \fB_post\fP .IP \(bu 2 ProtectedMemberHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms protected member names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { protected: int Member_Variable; } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { protected: int pre_member_variable_post; } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ProtectedMethodCase When defined, the check will ensure protected method names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ProtectedMethodPrefix When defined, the check will ensure protected method names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ProtectedMethodIgnoredRegexp Identifier naming checks won\(aqt be enforced for protected method names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ProtectedMethodSuffix When defined, the check will ensure protected method names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ProtectedMethodCase of \fBlower_case\fP .IP \(bu 2 ProtectedMethodPrefix of \fBpre_\fP .IP \(bu 2 ProtectedMethodSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms protect method names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { protected: int Member_Method(); } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { protected: int pre_member_method_post(); } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B PublicMemberCase When defined, the check will ensure public member names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B PublicMemberPrefix When defined, the check will ensure public member names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B PublicMemberIgnoredRegexp Identifier naming checks won\(aqt be enforced for public member names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B PublicMemberSuffix When defined, the check will ensure public member names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B PublicMemberHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 PublicMemberCase of \fBlower_case\fP .IP \(bu 2 PublicMemberPrefix of \fBpre_\fP .IP \(bu 2 PublicMemberSuffix of \fB_post\fP .IP \(bu 2 PublicMemberHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms public member names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { public: int Member_Variable; } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { public: int pre_member_variable_post; } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B PublicMethodCase When defined, the check will ensure public method names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B PublicMethodPrefix When defined, the check will ensure public method names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B PublicMethodIgnoredRegexp Identifier naming checks won\(aqt be enforced for public method names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B PublicMethodSuffix When defined, the check will ensure public method names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 PublicMethodCase of \fBlower_case\fP .IP \(bu 2 PublicMethodPrefix of \fBpre_\fP .IP \(bu 2 PublicMethodSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms public method names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { public: int Member_Method(); } .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C class Foo { public: int pre_member_method_post(); } .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B ScopedEnumConstantCase When defined, the check will ensure scoped enum constant names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B ScopedEnumConstantPrefix When defined, the check will ensure scoped enum constant names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ScopedEnumConstantIgnoredRegexp Identifier naming checks won\(aqt be enforced for scoped enum constant names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B ScopedEnumConstantSuffix When defined, the check will ensure scoped enum constant names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B ScopedEnumConstantHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 ScopedEnumConstantCase of \fBlower_case\fP .IP \(bu 2 ScopedEnumConstantPrefix of \fBpre_\fP .IP \(bu 2 ScopedEnumConstantSuffix of \fB_post\fP .IP \(bu 2 ScopedEnumConstantHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms enumeration constant names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C enum class FOO { One, Two, Three }; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C enum class FOO { pre_One_post, pre_Two_post, pre_Three_post }; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B StaticConstantCase When defined, the check will ensure static constant names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B StaticConstantPrefix When defined, the check will ensure static constant names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B StaticConstantIgnoredRegexp Identifier naming checks won\(aqt be enforced for static constant names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B StaticConstantSuffix When defined, the check will ensure static constant names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B StaticConstantHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 StaticConstantCase of \fBlower_case\fP .IP \(bu 2 StaticConstantPrefix of \fBpre_\fP .IP \(bu 2 StaticConstantSuffix of \fB_post\fP .IP \(bu 2 StaticConstantHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms static constant names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static unsigned const MyConstStatic_array[] = {1, 2, 3}; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static unsigned const pre_myconststatic_array_post[] = {1, 2, 3}; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B StaticVariableCase When defined, the check will ensure static variable names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B StaticVariablePrefix When defined, the check will ensure static variable names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B StaticVariableIgnoredRegexp Identifier naming checks won\(aqt be enforced for static variable names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B StaticVariableSuffix When defined, the check will ensure static variable names will add the suffix with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B StaticVariableHungarianPrefix When enabled, the check ensures that the declared identifier will have a Hungarian notation prefix based on the declared type. .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 StaticVariableCase of \fBlower_case\fP .IP \(bu 2 StaticVariablePrefix of \fBpre_\fP .IP \(bu 2 StaticVariableSuffix of \fB_post\fP .IP \(bu 2 StaticVariableHungarianPrefix of \fBOn\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms static variable names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static unsigned MyStatic_array[] = {1, 2, 3}; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C static unsigned pre_mystatic_array_post[] = {1, 2, 3}; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B StructCase When defined, the check will ensure struct names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B StructPrefix When defined, the check will ensure struct names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B StructIgnoredRegexp Identifier naming checks won\(aqt be enforced for struct names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B StructSuffix When defined, the check will ensure struct names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 StructCase of \fBlower_case\fP .IP \(bu 2 StructPrefix of \fBpre_\fP .IP \(bu 2 StructSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms struct names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct FOO { FOO(); ~FOO(); }; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C struct pre_foo_post { pre_foo_post(); ~pre_foo_post(); }; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B TemplateParameterCase When defined, the check will ensure template parameter names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B TemplateParameterPrefix When defined, the check will ensure template parameter names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B TemplateParameterIgnoredRegexp Identifier naming checks won\(aqt be enforced for template parameter names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B TemplateParameterSuffix When defined, the check will ensure template parameter names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 TemplateParameterCase of \fBlower_case\fP .IP \(bu 2 TemplateParameterPrefix of \fBpre_\fP .IP \(bu 2 TemplateParameterSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms template parameter names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C template class Foo {}; .ft P .fi .UNINDENT .UNINDENT .sp After: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C template class Foo {}; .ft P .fi .UNINDENT .UNINDENT .INDENT 0.0 .TP .B TemplateTemplateParameterCase When defined, the check will ensure template template parameter names conform to the selected casing. .UNINDENT .INDENT 0.0 .TP .B TemplateTemplateParameterPrefix When defined, the check will ensure template template parameter names will add the prefixed with the given value (regardless of casing). .UNINDENT .INDENT 0.0 .TP .B TemplateTemplateParameterIgnoredRegexp Identifier naming checks won\(aqt be enforced for template template parameter names matching this regular expression. .UNINDENT .INDENT 0.0 .TP .B TemplateTemplateParameterSuffix When defined, the check will ensure template template parameter names will add the suffix with the given value (regardless of casing). .UNINDENT .sp For example using values of: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 TemplateTemplateParameterCase of \fBlower_case\fP .IP \(bu 2 TemplateTemplateParameterPrefix of \fBpre_\fP .IP \(bu 2 TemplateTemplateParameterSuffix of \fB_post\fP .UNINDENT .UNINDENT .UNINDENT .sp Identifies and/or transforms template template parameter names as follows: .sp Before: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C template