Skip to content

Instantly share code, notes, and snippets.

@YenForYang
Last active June 23, 2021 02:42
Show Gist options
  • Save YenForYang/6543734260600845295affdbbb3bc4f1 to your computer and use it in GitHub Desktop.
Save YenForYang/6543734260600845295affdbbb3bc4f1 to your computer and use it in GitHub Desktop.
Fixable Clang-Tidy Checks
.. title:: clang-tidy - abseil-duration-addition
abseil-duration-addition
========================
Check for cases where addition should be performed in the ``absl::Time`` domain.
When adding two values, and one is known to be an ``absl::Time``, we can infer
that the other should be interpreted as an ``absl::Duration`` of a similar
scale, and make that inference explicit.
Examples:
.. code-block:: 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));
.. title:: clang-tidy - abseil-duration-comparison
abseil-duration-comparison
==========================
Checks for comparisons which should be in the ``absl::Duration`` domain instead
of the floating point or integer domains.
N.B.: In cases where a ``Duration`` was being converted to an integer and then
compared against a floating-point value, truncation during the ``Duration``
conversion might yield a different result. In practice this is very rare, and
still indicates a bug which should be fixed.
Examples:
.. code-block:: 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) ...
.. title:: clang-tidy - abseil-duration-conversion-cast
abseil-duration-conversion-cast
===============================
Checks for casts of ``absl::Duration`` conversion functions, and recommends
the right conversion function instead.
Examples:
.. code-block:: c++
// Original - Cast from a double to an integer
absl::Duration d;
int i = static_cast<int>(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<double>(absl::ToInt64Seconds(d));
// Suggested - Use the integer conversion function directly.
double x = absl::ToDoubleSeconds(d);
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 ``absl::Trunc`` to perform this operation explicitly instead.
.. title:: clang-tidy - abseil-duration-division
abseil-duration-division
========================
``absl::Duration`` arithmetic works like it does with integers. That means that
division of two ``absl::Duration`` objects returns an ``int64`` with any fractional
component truncated toward 0. See `this link <https://github.com/abseil/abseil-cpp/blob/29ff6d4860070bf8fcbd39c8805d0c32d56628a3/absl/time/time.h#L137>`_ for more information on arithmetic with ``absl::Duration``.
For example:
.. code-block:: 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);
If you want floating-point division, you should use either the
``absl::FDivDuration()`` function, or one of the unit conversion functions such
as ``absl::ToDoubleSeconds()``. For example:
.. code-block:: 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);
This check looks for uses of ``absl::Duration`` division that is done in a
floating-point context, and recommends the use of a function that returns a
floating-point value.
.. title:: clang-tidy - abseil-duration-factory-float
abseil-duration-factory-float
=============================
Checks for cases where the floating-point overloads of various
``absl::Duration`` factory functions are called when the more-efficient
integer versions could be used instead.
This check will not suggest fixes for literals which contain fractional
floating point values or non-literals. It will suggest removing
superfluous casts.
Examples:
.. code-block:: 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<double>(10));
// Suggested - Remove the explicit cast
absl::Duration d = absl::Seconds(10);
.. title:: clang-tidy - abseil-duration-factory-scale
abseil-duration-factory-scale
=============================
Checks for cases where arguments to ``absl::Duration`` 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
``absl::ZeroDuration()`` instead.
Examples:
.. code-block:: 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();
.. title:: clang-tidy - abseil-duration-subtraction
abseil-duration-subtraction
===========================
Checks for cases where subtraction should be performed in the
``absl::Duration`` domain. When subtracting two values, and the first one is
known to be a conversion from ``absl::Duration``, we can infer that the second
should also be interpreted as an ``absl::Duration``, and make that inference
explicit.
Examples:
.. code-block:: 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);
Note: As with other ``clang-tidy`` 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 ``clang-tidy`` multiple times will find and fix these
overlaps.
.. title:: clang-tidy - abseil-duration-unnecessary-conversion
abseil-duration-unnecessary-conversion
======================================
Finds and fixes cases where ``absl::Duration`` values are being converted to
numeric types and back again.
Floating-point examples:
.. code-block:: 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;
Integer examples:
.. code-block:: 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;
Unwrapping scalar operations:
.. code-block:: 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;
Note: Converting to an integer and back to an ``absl::Duration`` 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
``absl::Trunc`` to truncate explicitly.
.. title:: clang-tidy - abseil-faster-strsplit-delimiter
abseil-faster-strsplit-delimiter
================================
Finds instances of ``absl::StrSplit()`` or ``absl::MaxSplits()`` 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 ``absl::ByAnyChar()`` for just a single character
and will transform that into a single character as well.
These changes will give the same result, but using characters rather than
single character string literals is more efficient and readable.
Examples:
.. code-block:: c++
// Original - the argument is a string literal.
for (auto piece : absl::StrSplit(str, "B")) {
// Suggested - the argument is a character, which causes the more efficient
// overload of absl::StrSplit() to be used.
for (auto piece : absl::StrSplit(str, 'B')) {
// Original - the argument is a string literal inside absl::ByAnyChar call.
for (auto piece : absl::StrSplit(str, absl::ByAnyChar("B"))) {
// 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, 'B')) {
// Original - the argument is a string literal inside absl::MaxSplits call.
for (auto piece : absl::StrSplit(str, absl::MaxSplits("B", 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('B', 1))) {
.. title:: clang-tidy - abseil-redundant-strcat-calls
abseil-redundant-strcat-calls
=============================
Suggests removal of unnecessary calls to ``absl::StrCat`` when the result is
being passed to another call to ``absl::StrCat`` or ``absl::StrAppend``.
The extra calls cause unnecessary temporary strings to be constructed. Removing
them makes the code smaller and faster.
Examples:
.. code-block:: c++
std::string s = absl::StrCat("A", absl::StrCat("B", absl::StrCat("C", "D")));
//before
std::string s = absl::StrCat("A", "B", "C", "D");
//after
absl::StrAppend(&s, absl::StrCat("E", "F", "G"));
//before
absl::StrAppend(&s, "E", "F", "G");
//after
.. title:: clang-tidy - abseil-str-cat-append
abseil-str-cat-append
=====================
Flags uses of ``absl::StrCat()`` to append to a ``std::string``. Suggests
``absl::StrAppend()`` should be used instead.
The extra calls cause unnecessary temporary strings to be constructed. Removing
them makes the code smaller and faster.
.. code-block:: c++
a = absl::StrCat(a, b); // Use absl::StrAppend(&a, b) instead.
Does not diagnose cases where ``absl::StrCat()`` is used as a template
argument for a functor.
.. title:: clang-tidy - abseil-string-find-startswith
abseil-string-find-startswith
=============================
Checks whether a ``std::string::find()`` result is compared with 0, and
suggests replacing with ``absl::StartsWith()``. This is both a readability and
performance issue.
.. code-block:: c++
string s = "...";
if (s.find("Hello World") == 0) { /* do something */ }
becomes
.. code-block:: c++
string s = "...";
if (absl::StartsWith(s, "Hello World")) { /* do something */ }
Options
-------
.. option:: StringLikeClasses
Semicolon-separated list of names of string-like classes. By default only
``std::basic_string`` is considered. The list of methods to considered is
fixed.
.. option:: IncludeStyle
A string specifying which include-style is used, `llvm` or `google`. Default
is `llvm`.
.. option:: AbseilStringsMatchHeader
The location of Abseil's ``strings/match.h``. Defaults to
``absl/strings/match.h``.
.. title:: clang-tidy - abseil-string-find-str-contains
abseil-string-find-str-contains
===============================
Finds ``s.find(...) == string::npos`` comparisons (for various string-like types)
and suggests replacing with ``absl::StrContains()``.
This improves readability and reduces the likelihood of accidentally mixing
``find()`` and ``npos`` from different string-like types.
By default, "string-like types" includes ``::std::basic_string``,
``::std::basic_string_view``, and ``::absl::string_view``. See the
StringLikeClasses option to change this.
.. code-block:: c++
std::string s = "...";
if (s.find("Hello World") == std::string::npos) { /* do something */ }
absl::string_view a = "...";
if (absl::string_view::npos != a.find("Hello World")) { /* do something */ }
becomes
.. code-block:: c++
std::string s = "...";
if (!absl::StrContains(s, "Hello World")) { /* do something */ }
absl::string_view a = "...";
if (absl::StrContains(a, "Hello World")) { /* do something */ }
Options
-------
.. option:: StringLikeClasses
Semicolon-separated list of names of string-like classes. By default includes
``::std::basic_string``, ``::std::basic_string_view``, and
``::absl::string_view``.
.. option:: IncludeStyle
A string specifying which include-style is used, `llvm` or `google`. Default
is `llvm`.
.. option:: AbseilStringsMatchHeader
The location of Abseil's ``strings/match.h``. Defaults to
``absl/strings/match.h``.
.. title:: clang-tidy - abseil-time-comparison
abseil-time-comparison
======================
Prefer comparisons in the ``absl::Time`` domain instead of the integer domain.
N.B.: In cases where an ``absl::Time`` is being converted to an integer,
alignment may occur. If the comparison depends on this alignment, doing the
comparison in the ``absl::Time`` domain may yield a different result. In
practice this is very rare, and still indicates a bug which should be fixed.
Examples:
.. code-block:: 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) ...
.. title:: clang-tidy - abseil-time-subtraction
abseil-time-subtraction
=======================
Finds and fixes ``absl::Time`` subtraction expressions to do subtraction
in the Time domain instead of the numeric domain.
There are two cases of Time subtraction in which deduce additional type
information:
- When the result is an ``absl::Duration`` and the first argument is an
``absl::Time``.
- When the second argument is a ``absl::Time``.
In the first case, we must know the result of the operation, since without that
the second operand could be either an ``absl::Time`` or an ``absl::Duration``.
In the second case, the first operand *must* be an ``absl::Time``, because
subtracting an ``absl::Time`` from an ``absl::Duration`` is not defined.
Examples:
.. code-block:: c++
int x;
absl::Time t;
// Original - absl::Duration result and first operand is a 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);
.. title:: clang-tidy - abseil-upgrade-duration-conversions
abseil-upgrade-duration-conversions
===================================
Finds calls to ``absl::Duration`` arithmetic operators and factories whose
argument needs an explicit cast to continue compiling after upcoming API
changes.
The operators ``*=``, ``/=``, ``*``, and ``/`` for ``absl::Duration`` currently
accept an argument of class type that is convertible to an arithmetic type. Such
a call currently converts the value to an ``int64_t``, even in a case such as
``std::atomic<float>`` that would result in lossy conversion.
Additionally, the ``absl::Duration`` factory functions (``absl::Hours``,
``absl::Minutes``, etc) currently accept an ``int64_t`` 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 ``int64_t`` path.
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.
Here are example fixes created by this check:
.. code-block:: c++
std::atomic<int> a;
absl::Duration d = absl::Milliseconds(a);
d *= a;
becomes
.. code-block:: c++
std::atomic<int> a;
absl::Duration d = absl::Milliseconds(static_cast<int64_t>(a));
d *= static_cast<int64_t>(a);
Note that this check always adds a cast to ``int64_t`` 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.
.. title:: clang-tidy - altera-struct-pack-align
altera-struct-pack-align
========================
Finds structs that are inefficiently packed or aligned, and recommends
packing and/or aligning of said structs as needed.
Structs that are not packed take up more space than they should, and accessing
structs that are not well aligned is inefficient.
Fix-its are provided to fix both of these issues by inserting and/or amending
relevant struct attributes.
Based on the `Altera SDK for OpenCL: Best Practices Guide
<https://www.altera.com/en_US/pdfs/literature/hb/opencl-sdk/aocl_optimization_guide.pdf>`_.
.. code-block:: 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)));
.. title:: clang-tidy - android-cloexec-accept
android-cloexec-accept
======================
The usage of ``accept()`` is not recommended, it's better to use ``accept4()``.
Without this flag, an opened sensitive file descriptor would remain open across
a fork+exec to a lower-privileged SELinux domain.
Examples:
.. code-block:: c++
accept(sockfd, addr, addrlen);
// becomes
accept4(sockfd, addr, addrlen, SOCK_CLOEXEC);
.. title:: clang-tidy - android-cloexec-creat
android-cloexec-creat
=====================
The usage of ``creat()`` is not recommended, it's better to use ``open()``.
Examples:
.. code-block:: c++
int fd = creat(path, mode);
// becomes
int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, mode);
.. title:: clang-tidy - android-cloexec-dup
android-cloexec-dup
===================
The usage of ``dup()`` is not recommended, it's better to use ``fcntl()``,
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.
Examples:
.. code-block:: c++
int fd = dup(oldfd);
// becomes
int fd = fcntl(oldfd, F_DUPFD_CLOEXEC);
.. title:: clang-tidy - android-cloexec-pipe
android-cloexec-pipe
====================
This check detects usage of ``pipe()``. Using ``pipe()`` is not recommended, ``pipe2()`` 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.
Examples:
.. code-block:: c++
pipe(pipefd);
Suggested replacement:
.. code-block:: c++
pipe2(pipefd, O_CLOEXEC);
.. title:: clang-tidy - boost-use-to-string
boost-use-to-string
===================
This check finds conversion from integer type like ``int`` to ``std::string`` or
``std::wstring`` using ``boost::lexical_cast``, and replace it with calls to
``std::to_string`` and ``std::to_wstring``.
It doesn't replace conversion from floating points despite the ``to_string``
overloads, because it would change the behaviour.
.. code-block:: c++
auto str = boost::lexical_cast<std::string>(42);
auto wstr = boost::lexical_cast<std::wstring>(2137LL);
// Will be changed to
auto str = std::to_string(42);
auto wstr = std::to_wstring(2137LL);
.. title:: clang-tidy - bugprone-argument-comment
bugprone-argument-comment
=========================
Checks that argument comments match parameter names.
The check understands argument comments in the form ``/*parameter_name=*/``
that are placed right before the argument.
.. code-block:: c++
void f(bool foo);
...
f(/*bar=*/true);
// warning: argument name 'bar' in comment does not match parameter name 'foo'
The check tries to detect typos and suggest automated fixes for them.
Options
-------
.. option:: StrictMode
When `false` (default value), the check will ignore leading and trailing
underscores and case when comparing names -- otherwise they are taken into
account.
.. option:: IgnoreSingleArgument
When `true`, the check will ignore the single argument.
.. option:: CommentBoolLiterals
When `true`, the check will add argument comments in the format
``/*ParameterName=*/`` right before the boolean literal argument.
Before:
.. code-block:: c++
void foo(bool TurnKey, bool PressButton);
foo(true, false);
After:
.. code-block:: c++
void foo(bool TurnKey, bool PressButton);
foo(/*TurnKey=*/true, /*PressButton=*/false);
.. option:: CommentIntegerLiterals
When true, the check will add argument comments in the format
``/*ParameterName=*/`` right before the integer literal argument.
Before:
.. code-block:: c++
void foo(int MeaningOfLife);
foo(42);
After:
.. code-block:: c++
void foo(int MeaningOfLife);
foo(/*MeaningOfLife=*/42);
.. option:: CommentFloatLiterals
When true, the check will add argument comments in the format
``/*ParameterName=*/`` right before the float/double literal argument.
Before:
.. code-block:: c++
void foo(float Pi);
foo(3.14159);
After:
.. code-block:: c++
void foo(float Pi);
foo(/*Pi=*/3.14159);
.. option:: CommentStringLiterals
When true, the check will add argument comments in the format
``/*ParameterName=*/`` right before the string literal argument.
Before:
.. code-block:: c++
void foo(const char *String);
void foo(const wchar_t *WideString);
foo("Hello World");
foo(L"Hello World");
After:
.. code-block:: c++
void foo(const char *String);
void foo(const wchar_t *WideString);
foo(/*String=*/"Hello World");
foo(/*WideString=*/L"Hello World");
.. option:: CommentCharacterLiterals
When true, the check will add argument comments in the format
``/*ParameterName=*/`` right before the character literal argument.
Before:
.. code-block:: c++
void foo(char *Character);
foo('A');
After:
.. code-block:: c++
void foo(char *Character);
foo(/*Character=*/'A');
.. option:: CommentUserDefinedLiterals
When true, the check will add argument comments in the format
``/*ParameterName=*/`` right before the user defined literal argument.
Before:
.. code-block:: c++
void foo(double Distance);
double operator"" _km(long double);
foo(402.0_km);
After:
.. code-block:: c++
void foo(double Distance);
double operator"" _km(long double);
foo(/*Distance=*/402.0_km);
.. option:: CommentNullPtrs
When true, the check will add argument comments in the format
``/*ParameterName=*/`` right before the nullptr literal argument.
Before:
.. code-block:: c++
void foo(A* Value);
foo(nullptr);
After:
.. code-block:: c++
void foo(A* Value);
foo(/*Value=*/nullptr);
.. title:: clang-tidy - bugprone-bool-pointer-implicit-conversion
bugprone-bool-pointer-implicit-conversion
=========================================
Checks for conditions based on implicit conversion from a ``bool`` pointer to
``bool``.
Example:
.. code-block:: c++
bool *p;
if (p) {
// Never used in a pointer-specific way.
}
.. title:: clang-tidy - bugprone-copy-constructor-init
bugprone-copy-constructor-init
==============================
Finds copy constructors where the constructor doesn't call
the copy constructor of the base class.
.. code-block:: c++
class Copyable {
public:
Copyable() = default;
Copyable(const Copyable &) = default;
};
class X2 : public Copyable {
X2(const X2 &other) {} // Copyable(other) is missing
};
Also finds copy constructors where the constructor of
the base class don't have parameter.
.. code-block:: c++
class X4 : public Copyable {
X4(const X4 &other) : Copyable() {} // other is missing
};
The check also suggests a fix-its in some cases.
.. title:: clang-tidy - bugprone-implicit-widening-of-multiplication-result
bugprone-implicit-widening-of-multiplication-result
===================================================
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.
This is mainly useful when operating on a very large buffers.
For example, consider:
.. code-block:: 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;
}
}
}
This is fine in general, but iff ``width * height`` overflows,
you end up wrapping back to the beginning of ``base``
instead of processing the entire requested buffer.
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 "only" need a ~269MPix image.
Options
-------
.. option:: UseCXXStaticCastsInCppSources
When suggesting fix-its for C++ code, should C++-style ``static_cast<>()``'s
be suggested, or C-style casts. Defaults to ``true``.
.. option:: UseCXXHeadersInCppSources
When suggesting to include the appropriate header in C++ code,
should ``<cstddef>`` header be suggested, or ``<stddef.h>``.
Defaults to ``true``.
Examples:
.. code-block:: c++
long mul(int a, int b) {
return a * b; // warning: performing an implicit widening conversion to type 'long' of a multiplication performed in type 'int'
}
char* ptr_add(char *base, int a, int b) {
return base + a * b; // warning: result of multiplication in type 'int' is used as a pointer offset after an implicit widening conversion to type 'ssize_t'
}
char ptr_subscript(char *base, int a, int b) {
return base[a * b]; // warning: result of multiplication in type 'int' is used as a pointer offset after an implicit widening conversion to type 'ssize_t'
}
.. title:: clang-tidy - bugprone-inaccurate-erase
bugprone-inaccurate-erase
=========================
Checks for inaccurate use of the ``erase()`` method.
Algorithms like ``remove()`` 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
``erase()`` method. This check warns when not all of the elements will be
removed due to using an inappropriate overload.
For example, the following code erases only one element:
.. code-block:: c++
std::vector<int> xs;
...
xs.erase(std::remove(xs.begin(), xs.end(), 10));
Call the two-argument overload of ``erase()`` to remove the subrange:
.. code-block:: c++
std::vector<int> xs;
...
xs.erase(std::remove(xs.begin(), xs.end(), 10), xs.end());
.. title:: clang-tidy - bugprone-macro-parentheses
bugprone-macro-parentheses
==========================
Finds macros that can have unexpected behaviour due to missing parentheses.
Macros are expanded by the preprocessor as-is. As a result, there can be
unexpected behaviour; operators may be evaluated in unexpected order and
unary operators may become binary operators, etc.
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.
It is also recommended to surround macro arguments in the replacement list
with parentheses. This ensures that the argument value is calculated
properly.
.. title:: clang-tidy - bugprone-misplaced-operator-in-strlen-in-alloc
bugprone-misplaced-operator-in-strlen-in-alloc
==============================================
Finds cases where ``1`` is added to the string in the argument to ``strlen()``,
``strnlen()``, ``strnlen_s()``, ``wcslen()``, ``wcsnlen()``, and ``wcsnlen_s()``
instead of the result and the value is used as an argument to a memory
allocation function (``malloc()``, ``calloc()``, ``realloc()``, ``alloca()``) or
the ``new[]`` operator in `C++`. The check detects error cases even if one of
these functions (except the ``new[]`` operator) is called by a constant function
pointer. Cases where ``1`` is added both to the parameter and the result of the
``strlen()``-like function are ignored, as are cases where the whole addition is
surrounded by extra parentheses.
`C` example code:
.. code-block:: c
void bad_malloc(char *str) {
char *c = (char*) malloc(strlen(str + 1));
}
The suggested fix is to add ``1`` to the return value of ``strlen()`` and not
to its argument. In the example above the fix would be
.. code-block:: c
char *c = (char*) malloc(strlen(str) + 1);
`C++` example code:
.. code-block:: c++
void bad_new(char *str) {
char *c = new char[strlen(str + 1)];
}
As in the `C` code with the ``malloc()`` function, the suggested fix is to
add ``1`` to the return value of ``strlen()`` and not to its argument. In the
example above the fix would be
.. code-block:: c++
char *c = new char[strlen(str) + 1];
Example for silencing the diagnostic:
.. code-block:: c
void bad_malloc(char *str) {
char *c = (char*) malloc(strlen((str + 1)));
}
.. title:: clang-tidy - bugprone-misplaced-pointer-arithmetic-in-alloc
bugprone-misplaced-pointer-arithmetic-in-alloc
===============================================
Finds cases where an integer expression is added to or subtracted from the
result of a memory allocation function (``malloc()``, ``calloc()``,
``realloc()``, ``alloca()``) instead of its argument. The check detects error
cases even if one of these functions is called by a constant function pointer.
Example code:
.. code-block:: c
void bad_malloc(int n) {
char *p = (char*) malloc(n) + 10;
}
The suggested fix is to add the integer expression to the argument of
``malloc`` and not to its result. In the example above the fix would be
.. code-block:: c
char *p = (char*) malloc(n + 10);
.. title:: clang-tidy - bugprone-move-forwarding-reference
bugprone-move-forwarding-reference
==================================
Warns if ``std::move`` is called on a forwarding reference, for example:
.. code-block:: c++
template <typename T>
void foo(T&& t) {
bar(std::move(t));
}
`Forwarding references
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4164.pdf>`_ should
typically be passed to ``std::forward`` instead of ``std::move``, and this is
the fix that will be suggested.
(A forwarding reference is an rvalue reference of a type that is a deduced
function template argument.)
In this example, the suggested fix would be
.. code-block:: c++
bar(std::forward<T>(t));
Background
----------
Code like the example above is sometimes written with the expectation that
``T&&`` will always end up being an rvalue reference, no matter what type is
deduced for ``T``, and that it is therefore not possible to pass an lvalue to
``foo()``. However, this is not true. Consider this example:
.. code-block:: c++
std::string s = "Hello, world";
foo(s);
This code compiles and, after the call to ``foo()``, ``s`` is left in an
indeterminate state because it has been moved from. This may be surprising to
the caller of ``foo()`` because no ``std::move`` was used when calling
``foo()``.
The reason for this behavior lies in the special rule for template argument
deduction on function templates like ``foo()`` -- 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.)
If ``foo()`` is called on an lvalue (as in the example above), then ``T`` is
deduced to be an lvalue reference. In the example, ``T`` is deduced to be
``std::string &``. The type of the argument ``t`` therefore becomes
``std::string& &&``; by the reference collapsing rules, this collapses to
``std::string&``.
This means that the ``foo(s)`` call passes ``s`` as an lvalue reference, and
``foo()`` ends up moving ``s`` and thereby placing it into an indeterminate
state.
.. title:: clang-tidy - bugprone-not-null-terminated-result
bugprone-not-null-terminated-result
===================================
Finds function calls where it is possible to cause a not null-terminated result.
Usually the proper length of a string is ``strlen(src) + 1`` or equal length of
this expression, because the null terminator needs an extra space. Without the
null terminator it can result in undefined behaviour when the string is read.
The following and their respective ``wchar_t`` based functions are checked:
``memcpy``, ``memcpy_s``, ``memchr``, ``memmove``, ``memmove_s``,
``strerror_s``, ``strncmp``, ``strxfrm``
The following is a real-world example where the programmer forgot to increase
the passed third argument, which is ``size_t length``. That is why the length
of the allocated memory is not enough to hold the null terminator.
.. code-block:: c
static char *stringCpy(const std::string &str) {
char *result = reinterpret_cast<char *>(malloc(str.size()));
memcpy(result, str.data(), str.size());
return result;
}
In addition to issuing warnings, fix-it rewrites all the necessary code. It also
tries to adjust the capacity of the destination array:
.. code-block:: c
static char *stringCpy(const std::string &str) {
char *result = reinterpret_cast<char *>(malloc(str.size() + 1));
strcpy(result, str.data());
return result;
}
Note: It cannot guarantee to rewrite every of the path-sensitive memory
allocations.
.. _MemcpyTransformation:
Transformation rules of 'memcpy()'
----------------------------------
It is possible to rewrite the ``memcpy()`` and ``memcpy_s()`` calls as the
following four functions: ``strcpy()``, ``strncpy()``, ``strcpy_s()``,
``strncpy_s()``, where the latter two are the safer versions of the former two.
It rewrites the ``wchar_t`` based memory handler functions respectively.
Rewrite based on the destination array
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- If copy to the destination array cannot overflow [1] the new function should
be the older copy function (ending with ``cpy``), because it is more
efficient than the safe version.
- If copy to the destination array can overflow [1] and
:option:`WantToUseSafeFunctions` is set to `true` and it is possible to
obtain the capacity of the destination array then the new function could be
the safe version (ending with ``cpy_s``).
- If the new function is could be safe version and C++ files are analysed and
the destination array is plain ``char``/``wchar_t`` without ``un/signed`` then
the length of the destination array can be omitted.
- If the new function is could be safe version and the destination array is
``un/signed`` it needs to be casted to plain ``char *``/``wchar_t *``.
[1] It is possible to overflow:
- If the capacity of the destination array is unknown.
- If the given length is equal to the destination array's capacity.
Rewrite based on the length of the source string
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- If the given length is ``strlen(source)`` or equal length of this expression
then the new function should be the older copy function (ending with ``cpy``),
as it is more efficient than the safe version (ending with ``cpy_s``).
- Otherwise we assume that the programmer wanted to copy 'N' characters, so the
new function is ``ncpy``-like which copies 'N' characters.
Transformations with 'strlen()' or equal length of this expression
------------------------------------------------------------------
It transforms the ``wchar_t`` based memory and string handler functions
respectively (where only ``strerror_s`` does not have ``wchar_t`` based alias).
Memory handler functions
^^^^^^^^^^^^^^^^^^^^^^^^
``memcpy``
Please visit the
:ref:`Transformation rules of 'memcpy()'<MemcpyTransformation>` section.
``memchr``
Usually there is a C-style cast and it is needed to be removed, because the
new function ``strchr``'s return type is correct. The given length is going
to be removed.
``memmove``
If safe functions are available the new function is ``memmove_s``, 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.
``memmove_s``
The given length is incremented by one.
String handler functions
^^^^^^^^^^^^^^^^^^^^^^^^
``strerror_s``
The given length is incremented by one.
``strncmp``
If the third argument is the first or the second argument's ``length + 1``
it has to be truncated without the ``+ 1`` operation.
``strxfrm``
The given length is incremented by one.
Options
-------
.. option:: WantToUseSafeFunctions
The value `true` specifies that the target environment is considered to
implement '_s' suffixed memory and string handler functions which are safer
than older versions (e.g. 'memcpy_s()'). The default value is `true`.
.. title:: clang-tidy - bugprone-parent-virtual-call
bugprone-parent-virtual-call
============================
Detects and fixes calls to grand-...parent virtual methods instead of calls
to overridden parent's virtual methods.
.. code-block:: 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 'B'? [bugprone-parent-virtual-call]
};
.. title:: clang-tidy - bugprone-posix-return
bugprone-posix-return
=====================
Checks if any calls to ``pthread_*`` or ``posix_*`` functions
(except ``posix_openpt``) expect negative return values. These functions return
either ``0`` on success or an ``errno`` on failure, which is positive only.
Example buggy usage looks like:
.. code-block:: c
if (posix_fadvise(...) < 0) {
This will never happen as the return value is always non-negative. A simple fix could be:
.. code-block:: c
if (posix_fadvise(...) > 0) {
.. title:: clang-tidy - bugprone-redundant-branch-condition
bugprone-redundant-branch-condition
===================================
Finds condition variables in nested ``if`` statements that were also checked in
the outer ``if`` statement and were not changed.
Simple example:
.. code-block:: c
bool onFire = isBurning();
if (onFire) {
if (onFire)
scream();
}
Here `onFire` is checked both in the outer ``if`` and the inner ``if`` statement
without a possible change between the two checks. The check warns for this code
and suggests removal of the second checking of variable `onFire`.
The checker also detects redundant condition checks if the condition variable
is an operand of a logical "and" (``&&``) or a logical "or" (``||``) operator:
.. code-block:: c
bool onFire = isBurning();
if (onFire) {
if (onFire && peopleInTheBuilding > 0)
scream();
}
.. code-block:: c
bool onFire = isBurning();
if (onFire) {
if (onFire || isCollapsing())
scream();
}
In the first case (logical "and") the suggested fix is to remove the redundant
condition variable and keep the other side of the ``&&``. In the second case
(logical "or") the whole ``if`` is removed similarily to the simple case on the
top.
The condition of the outer ``if`` statement may also be a logical "and" (``&&``)
expression:
.. code-block:: c
bool onFire = isBurning();
if (onFire && fireFighters < 10) {
if (someOtherCondition()) {
if (onFire)
scream();
}
}
The error is also detected if both the outer statement is a logical "and"
(``&&``) and the inner statement is a logical "and" (``&&``) or "or" (``||``).
The inner ``if`` statement does not have to be a direct descendant of the outer
one.
No error is detected if the condition variable may have been changed between the
two checks:
.. code-block:: c
bool onFire = isBurning();
if (onFire) {
tryToExtinguish(onFire);
if (onFire && peopleInTheBuilding > 0)
scream();
}
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.
Known limitations
^^^^^^^^^^^^^^^^^
The ``else`` branch is not checked currently for negated condition variable:
.. code-block:: c
bool onFire = isBurning();
if (onFire) {
scream();
} else {
if (!onFire) {
continueWork();
}
}
The checker currently only detects redundant checking of single condition
variables. More complex expressions are not checked:
.. code-block:: c
if (peopleInTheBuilding == 1) {
if (peopleInTheBuilding == 1) {
doSomething();
}
}
.. title:: clang-tidy - bugprone-reserved-identifier
bugprone-reserved-identifier
============================
`cert-dcl37-c` and `cert-dcl51-cpp` redirect here as an alias for this check.
Checks for usages of identifiers reserved for use by the implementation.
The C and C++ standards both reserve the following names for such use:
- identifiers that begin with an underscore followed by an uppercase letter;
- identifiers in the global namespace that begin with an underscore.
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.
Violating the naming rules above results in undefined behavior.
.. code-block:: 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
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't infringe on the user
namespace.
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++ 'zombie names' and C future library directions.
This check corresponds to CERT C Coding Standard rule `DCL37-C. Do not declare
or define a reserved identifier
<https://wiki.sei.cmu.edu/confluence/display/c/DCL37-C.+Do+not+declare+or+define+a+reserved+identifier>`_
as well as its C++ counterpart, `DCL51-CPP. Do not declare or define a reserved
identifier
<https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL51-CPP.+Do+not+declare+or+define+a+reserved+identifier>`_.
Options
-------
.. option:: Invert
If `true`, inverts the check, i.e. flags names that are not reserved.
Default is `false`.
.. option:: AllowedIdentifiers
Semicolon-separated list of names that the check ignores. Default is an
empty list.
.. title:: clang-tidy - bugprone-string-constructor
bugprone-string-constructor
===========================
Finds string constructors that are suspicious and probably errors.
A common mistake is to swap parameters to the 'fill' string-constructor.
Examples:
.. code-block:: c++
std::string str('x', 50); // should be str(50, 'x')
Calling the string-literal constructor with a length bigger than the literal is
suspicious and adds extra random characters to the string.
Examples:
.. code-block:: c++
std::string("test", 200); // Will include random characters after "test".
std::string_view("test", 200);
Creating an empty string from constructors with parameters is considered
suspicious. The programmer should use the empty constructor instead.
Examples:
.. code-block:: c++
std::string("test", 0); // Creation of an empty string.
std::string_view("test", 0);
Options
-------
.. option:: WarnOnLargeLength
When `true`, the check will warn on a string with a length greater than
:option:`LargeLengthThreshold`. Default is `true`.
.. option:: LargeLengthThreshold
An integer specifying the large length threshold. Default is `0x800000`.
.. option:: StringNames
Default is `::std::basic_string;::std::basic_string_view`.
Semicolon-delimited list of class names to apply this check to.
By default `::std::basic_string` applies to ``std::string`` and
``std::wstring``. Set to e.g. `::std::basic_string;llvm::StringRef;QString`
to perform this check on custom classes.
.. title:: clang-tidy - bugprone-string-integer-assignment
bugprone-string-integer-assignment
==================================
The check finds assignments of an integer to ``std::basic_string<CharT>``
(``std::string``, ``std::wstring``, etc.). The source of the problem is the
following assignment operator of ``std::basic_string<CharT>``:
.. code-block:: c++
basic_string& operator=( CharT ch );
Numeric types can be implicitly casted to character types.
.. code-block:: c++
std::string s;
int x = 5965;
s = 6;
s = x;
Use the appropriate conversion functions or character literals.
.. code-block:: c++
std::string s;
int x = 5965;
s = '6';
s = std::to_string(x);
In order to suppress false positives, use an explicit cast.
.. code-block:: c++
std::string s;
s = static_cast<char>(6);
.. title:: clang-tidy - bugprone-suspicious-memset-usage
bugprone-suspicious-memset-usage
================================
This check finds ``memset()`` calls with potential mistakes in their arguments.
Considering the function as ``void* memset(void* destination, int fill_value,
size_t byte_count)``, the following cases are covered:
**Case 1: Fill value is a character ``'0'``**
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 ``'0'`` with ``0``. Memsetting character
pointers with ``'0'`` is allowed.
**Case 2: Fill value is truncated**
Memset converts ``fill_value`` to ``unsigned char`` before using it. If
``fill_value`` is out of unsigned character range, it gets truncated
and memory will not contain the desired pattern.
**Case 3: Byte count is zero**
Calling memset with a literal zero in its ``byte_count`` argument is likely
to be unintended and swapped with ``fill_value``. The check offers to swap
these two arguments.
Corresponding cpplint.py check name: ``runtime/memset``.
Examples:
.. code-block:: c++
void foo() {
int i[5] = {1, 2, 3, 4, 5};
int *ip = i;
char c = '1';
char *cp = &c;
int v = 0;
// Case 1
memset(ip, '0', 1); // suspicious
memset(cp, '0', 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
}
.. title:: clang-tidy - bugprone-suspicious-semicolon
bugprone-suspicious-semicolon
=============================
Finds most instances of stray semicolons that unexpectedly alter the meaning of
the code. More specifically, it looks for ``if``, ``while``, ``for`` and
``for-range`` 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.
.. code-block:: c++
if (x < y);
{
x++;
}
Here the body of the ``if`` statement consists of only the semicolon at the end
of the first line, and `x` will be incremented regardless of the condition.
.. code-block:: c++
while ((line = readLine(file)) != NULL);
processLine(line);
As a result of this code, `processLine()` will only be called once, when the
``while`` loop with the empty body exits with `line == NULL`. The indentation of
the code indicates the intention of the programmer.
.. code-block:: c++
if (x >= y);
x -= y;
While the indentation does not imply any nesting, there is simply no valid
reason to have an `if` statement with an empty body (but it can make sense for
a loop). So this check issues a warning for the code above.
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:
.. code-block:: c++
while (readWhitespace());
Token t = readNextToken();
Here the second line is indented in a way that suggests that it is meant to be
the body of the `while` loop - whose body is in fact empty, because of the
semicolon at the end of the first line.
Either remove the indentation from the second line:
.. code-block:: c++
while (readWhitespace());
Token t = readNextToken();
... or move the semicolon from the end of the first line to a new line:
.. code-block:: c++
while (readWhitespace())
;
Token t = readNextToken();
In this case the check will assume that you know what you are doing, and will
not raise a warning.
.. title:: clang-tidy - bugprone-suspicious-string-compare
bugprone-suspicious-string-compare
==================================
Find suspicious usage of runtime string comparison functions.
This check is valid in C and C++.
Checks for calls with implicit comparator and proposed to explicitly add it.
.. code-block:: c++
if (strcmp(...)) // Implicitly compare to zero
if (!strcmp(...)) // Won't warn
if (strcmp(...) != 0) // Won't warn
Checks that compare function results (i,e, ``strcmp``) are compared to valid
constant. The resulting value is
.. code::
< 0 when lower than,
> 0 when greater than,
== 0 when equals.
A common mistake is to compare the result to `1` or `-1`.
.. code-block:: c++
if (strcmp(...) == -1) // Incorrect usage of the returned value.
Additionally, the check warns if the results value is implicitly cast to a
*suspicious* non-integer type. It's happening when the returned value is used in
a wrong context.
.. code-block:: c++
if (strcmp(...) < 0.) // Incorrect usage of the returned value.
Options
-------
.. option:: WarnOnImplicitComparison
When `true`, the check will warn on implicit comparison. `true` by default.
.. option:: WarnOnLogicalNotComparison
When `true`, the check will warn on logical not comparison. `false` by default.
.. option:: 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:
`__builtin_memcmp`, `__builtin_strcasecmp`, `__builtin_strcmp`,
`__builtin_strncasecmp`, `__builtin_strncmp`, `_mbscmp`, `_mbscmp_l`,
`_mbsicmp`, `_mbsicmp_l`, `_mbsnbcmp`, `_mbsnbcmp_l`, `_mbsnbicmp`,
`_mbsnbicmp_l`, `_mbsncmp`, `_mbsncmp_l`, `_mbsnicmp`, `_mbsnicmp_l`,
`_memicmp`, `_memicmp_l`, `_stricmp`, `_stricmp_l`, `_strnicmp`,
`_strnicmp_l`, `_wcsicmp`, `_wcsicmp_l`, `_wcsnicmp`, `_wcsnicmp_l`,
`lstrcmp`, `lstrcmpi`, `memcmp`, `memicmp`, `strcasecmp`, `strcmp`,
`strcmpi`, `stricmp`, `strncasecmp`, `strncmp`, `strnicmp`, `wcscasecmp`,
`wcscmp`, `wcsicmp`, `wcsncmp`, `wcsnicmp`, `wmemcmp`.
.. title:: clang-tidy - bugprone-swapped-arguments
bugprone-swapped-arguments
==========================
Finds potentially swapped arguments by looking at implicit conversions.
.. title:: clang-tidy - bugprone-terminating-continue
bugprone-terminating-continue
=============================
Detects ``do while`` loops with a condition always evaluating to false that
have a ``continue`` statement, as this ``continue`` terminates the loop
effectively.
.. code-block:: c++
void f() {
do {
// some code
continue; // terminating continue
// some other code
} while(false);
.. title:: clang-tidy - bugprone-unused-raii
bugprone-unused-raii
====================
Finds temporaries that look like RAII objects.
The canonical example for this is a scoped lock.
.. code-block:: c++
{
scoped_lock(&global_mutex);
critical_section();
}
The destructor of the scoped_lock is called before the ``critical_section`` is
entered, leaving it unprotected.
We apply a number of heuristics to reduce the false positive count of this
check:
- Ignore code expanded from macros. Testing frameworks make heavy use of this.
- Ignore types with trivial destructors. They are very unlikely to be RAII
objects and there's no difference when they are deleted.
- Ignore objects at the end of a compound statement (doesn't change behavior).
- Ignore objects returned from a call.
.. title:: clang-tidy - bugprone-virtual-near-miss
bugprone-virtual-near-miss
==========================
Warn if a function is a near miss (ie. the name is very similar and the function
signature is the same) to a virtual function from a base class.
Example:
.. code-block:: c++
struct Base {
virtual void func();
};
struct Derived : Base {
virtual funk();
// warning: 'Derived::funk' has a similar name and the same signature as virtual method 'Base::func'; did you mean to override it?
};
.. title:: clang-tidy - cppcoreguidelines-init-variables
cppcoreguidelines-init-variables
================================
Checks whether there are local variables that are declared without an initial
value. These may lead to unexpected behaviour if there is a code path that reads
the variable before assigning to it.
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.
As an example a function that looks like this:
.. code-block:: c++
void function() {
int x;
char *txt;
double d;
// Rest of the function.
}
Would be rewritten to look like this:
.. code-block:: c++
#include <math.h>
void function() {
int x = 0;
char *txt = nullptr;
double d = NAN;
// Rest of the function.
}
Options
-------
.. option:: IncludeStyle
A string specifying which include-style is used, `llvm` or `google`. Default
is `llvm`.
.. option:: MathHeader
A string specifying the header to include to get the definition of `NAN`.
Default is `<math.h>`.
.. title:: clang-tidy - cppcoreguidelines-prefer-member-initializer
cppcoreguidelines-prefer-member-initializer
===========================================
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.
This check implements `C.49 <https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c49-prefer-initialization-to-assignment-in-constructors>`_ from the CppCoreGuidelines.
If the language version is `C++ 11` 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 `C++ 20`), furthermore the assigned value is a literal,
negated literal or ``enum`` constant then the preferred place of the
initialization is at the class member declaration.
This latter rule is `C.48 <https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c48-prefer-in-class-initializers-to-member-initializers-in-constructors-for-constant-initializers>`_ from CppCoreGuidelines.
Please note, that this check does not enforce this latter rule for
initializations already implemented as member initializers. For that purpose
see check `modernize-use-default-member-init <modernize-use-default-member-init.html>`_.
Example 1
---------
.. code-block:: c++
class C {
int n;
int m;
public:
C() {
n = 1; // Literal in default constructor
if (dice())
return;
m = 1;
}
};
Here ``n`` can be initialized using a default member initializer, unlike
``m``, as ``m``'s initialization follows a control statement (``if``):
.. code-block:: c++
class C {
int n{1};
int m;
public:
C() {
if (dice())
return;
m = 1;
}
Example 2
---------
.. code-block:: 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;
}
};
Here ``n`` can be initialized in the constructor initialization list, unlike
``m``, as ``m``'s initialization follows a control statement (``if``):
.. code-block:: c++
C(int nn, int mm) : n(nn) {
if (dice())
return;
m = mm;
}
.. option:: UseAssignment
If this option is set to `true` (default is `false`), the check will initialize
members with an assignment. In this case the fix of the first example looks
like this:
.. code-block:: c++
class C {
int n = 1;
int m;
public:
C() {
if (dice())
return;
m = 1;
}
};
.. title:: clang-tidy - cppcoreguidelines-pro-bounds-constant-array-index
cppcoreguidelines-pro-bounds-constant-array-index
=================================================
This check flags all array subscript expressions on static arrays and
``std::arrays`` that either do not have a constant integer expression index or
are out of bounds (for ``std::array``). For out-of-bounds checking of static
arrays, see the `-Warray-bounds` Clang diagnostic.
This rule is part of the "Bounds safety" profile of the C++ Core Guidelines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-bounds-arrayindex.
Options
-------
.. option:: GslHeader
The check can generate fixes after this option has been set to the name of
the include file that contains ``gsl::at()``, e.g. `"gsl/gsl.h"`.
.. option:: IncludeStyle
A string specifying which include-style is used, `llvm` or `google`. Default
is `llvm`.
.. title:: clang-tidy - cppcoreguidelines-pro-type-cstyle-cast
cppcoreguidelines-pro-type-cstyle-cast
======================================
This check flags all use of C-style casts that perform a ``static_cast``
downcast, ``const_cast``, or ``reinterpret_cast``.
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 ``(T)expression`` cast means to perform the first of
the following that is possible: a ``const_cast``, a ``static_cast``, a
``static_cast`` followed by a ``const_cast``, a ``reinterpret_cast``, or a
``reinterpret_cast`` followed by a ``const_cast``. This rule bans
``(T)expression`` only when used to perform an unsafe cast.
This rule is part of the "Type safety" profile of the C++ Core Guidelines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-type-cstylecast.
.. title:: clang-tidy - cppcoreguidelines-pro-type-member-init
cppcoreguidelines-pro-type-member-init
======================================
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't initialized, the constructor will leave
some of the memory in an undefined state.
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.
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.
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 ``{}`` for C++11 and beyond or ``=
{}`` for older language versions.
Options
-------
.. option:: IgnoreArrays
If set to `true`, 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 `false`.
.. option:: UseAssignment
If set to `true`, the check will provide fix-its with literal initializers
\( ``int i = 0;`` \) instead of curly braces \( ``int i{};`` \).
This rule is part of the "Type safety" profile of the C++ Core
Guidelines, corresponding to rule Type.6. See
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-type-memberinit.
.. title:: clang-tidy - cppcoreguidelines-pro-type-static-cast-downcast
cppcoreguidelines-pro-type-static-cast-downcast
===============================================
This check flags all usages of ``static_cast``, where a base class is casted to
a derived class. In those cases, a fix-it is provided to convert the cast to a
``dynamic_cast``.
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``.
This rule is part of the "Type safety" profile of the C++ Core Guidelines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-type-downcast.
.. title:: clang-tidy - darwin-dispatch-once-nonstatic
darwin-dispatch-once-nonstatic
==============================
Finds declarations of ``dispatch_once_t`` variables without static or global
storage. The behavior of using ``dispatch_once_t`` predicates with automatic or
dynamic storage is undefined by libdispatch, and should be avoided.
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 ``dispatch_once_t`` predicate, leading to an uninitialized flag
value at the mercy of the stack.
Programmers have also been known to make ``dispatch_once_t`` 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.
See the discussion section of
`Apple's dispatch_once documentation <https://developer.apple.com/documentation/dispatch/1447169-dispatch_once>`_
for more information.
.. title:: clang-tidy - fuchsia-default-arguments-declarations
fuchsia-default-arguments-declarations
======================================
Warns if a function or method is declared with default parameters.
For example, the declaration:
.. code-block:: c++
int foo(int value = 5) { return value; }
will cause a warning.
See the features disallowed in Fuchsia at https://fuchsia.googlesource.com/zircon/+/master/docs/cxx.md
.. title:: clang-tidy - google-explicit-constructor
google-explicit-constructor
===========================
Checks that constructors callable with a single argument and conversion
operators are marked explicit to avoid the risk of unintentional implicit
conversions.
Consider this example:
.. code-block:: c++
struct S {
int x;
operator bool() const { return true; }
};
bool f() {
S a{1};
S b{2};
return a == b;
}
The function will return ``true``, since the objects are implicitly converted to
``bool`` before comparison, which is unlikely to be the intent.
The check will suggest inserting ``explicit`` before the constructor or
conversion operator declaration. However, copy and move constructors should not
be explicit, as well as constructors taking a single ``initializer_list``
argument.
This code:
.. code-block:: c++
struct S {
S(int a);
explicit S(const S&);
operator bool() const;
...
will become
.. code-block:: c++
struct S {
explicit S(int a);
S(const S&);
explicit operator bool() const;
...
See https://google.github.io/styleguide/cppguide.html#Explicit_Constructors
.. title:: clang-tidy - google-upgrade-googletest-case
google-upgrade-googletest-case
==============================
Finds uses of deprecated Google Test version 1.9 APIs with names containing
``case`` and replaces them with equivalent APIs with ``suite``.
All names containing ``case`` are being replaced to be consistent with the
meanings of "test case" and "test suite" as used by the International
Software Testing Qualifications Board and ISO 29119.
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.
The affected APIs are:
- Member functions of ``testing::Test``, ``testing::TestInfo``,
``testing::TestEventListener``, ``testing::UnitTest``, and any type inheriting
from these types
- The macros ``TYPED_TEST_CASE``, ``TYPED_TEST_CASE_P``,
``REGISTER_TYPED_TEST_CASE_P``, and ``INSTANTIATE_TYPED_TEST_CASE_P``
- The type alias ``testing::TestCase``
Examples of fixes created by this check:
.. code-block:: c++
class FooTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
};
TYPED_TEST_CASE(BarTest, BarTypes);
becomes
.. code-block:: c++
class FooTest : public testing::Test {
public:
static void SetUpTestSuite();
static void TearDownTestSuite();
};
TYPED_TEST_SUITE(BarTest, BarTypes);
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 a only warning when a fix cannot be made safely, as is the case
with some template and macro uses.
.. title:: clang-tidy - llvm-include-order
llvm-include-order
==================
Checks the correct order of ``#includes``.
See https://llvm.org/docs/CodingStandards.html#include-style
.. title:: clang-tidy - llvm-prefer-isa-or-dyn-cast-in-conditionals
llvm-prefer-isa-or-dyn-cast-in-conditionals
===========================================
Looks at conditionals and finds and replaces cases of ``cast<>``,
which will assert rather than return a null pointer, and
``dyn_cast<>`` where the return value is not captured. Additionally,
finds and replaces cases that match the pattern ``var &&
isa<X>(var)``, where ``var`` is evaluated twice.
.. code-block:: c++
// Finds these:
if (auto x = cast<X>(y)) {}
// is replaced by:
if (auto x = dyn_cast<X>(y)) {}
if (cast<X>(y)) {}
// is replaced by:
if (isa<X>(y)) {}
if (dyn_cast<X>(y)) {}
// is replaced by:
if (isa<X>(y)) {}
if (var && isa<T>(var)) {}
// is replaced by:
if (isa_and_nonnull<T>(var.foo())) {}
// Other cases are ignored, e.g.:
if (auto f = cast<Z>(y)->foo()) {}
if (cast<Z>(y)->foo()) {}
if (X.cast(y)) {}
.. title:: clang-tidy - llvm-prefer-register-over-unsigned
llvm-prefer-register-over-unsigned
==================================
Finds historical use of ``unsigned`` to hold vregs and physregs and rewrites
them to use ``Register``.
Currently this works by finding all variables of unsigned integer type whose
initializer begins with an implicit cast from ``Register`` to ``unsigned``.
.. code-block:: c++
void example(MachineOperand &MO) {
unsigned Reg = MO.getReg();
...
}
becomes:
.. code-block:: c++
void example(MachineOperand &MO) {
Register Reg = MO.getReg();
...
}
.. title:: clang-tidy - llvm-twine-local
llvm-twine-local
================
Looks for local ``Twine`` variables which are prone to use after frees and
should be generally avoided.
.. code-block:: c++
static Twine Moo = Twine("bark") + "bah";
// becomes
static std::string Moo = (Twine("bark") + "bah").str();
.. title:: clang-tidy - llvmlibc-restrict-system-libc-headers
llvmlibc-restrict-system-libc-headers
=====================================
Finds includes of system libc headers not provided by the compiler within
llvm-libc implementations.
.. code-block:: c++
#include <stdio.h> // Not allowed because it is part of system libc.
#include <stddef.h> // Allowed because it is provided by the compiler.
#include "internal/stdio.h" // Allowed because it is NOT part of system libc.
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 ``dirent`` 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.
Options
-------
.. option:: 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 `*` and `-`, to include and exclude globs,
respectively. The default is `-*`, which disallows all includes.
This can be used to allow known safe includes such as Linux development
headers. See :doc:`portability-restrict-system-includes
<portability-restrict-system-includes>` for more
details.
.. title:: clang-tidy - misc-definitions-in-headers
misc-definitions-in-headers
===========================
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.
.. code-block:: 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 = "foo";
// 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 = "foo";
constexpr int k = 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<typename T>
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 <typename T>
struct B {
void f1();
};
// OK: member function definition of a class template is allowed.
template <typename T>
void B<T>::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 <class T>
constexpr T pi = T(3.1415926L);
Options
-------
.. option:: HeaderFileExtensions
A comma-separated list of filename extensions of header files (the filename
extensions should not include "." prefix). Default is "h,hh,hpp,hxx".
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.,
"h,hh,hpp,hxx," (note the trailing comma).
.. option:: UseHeaderFileExtension
When `true`, the check will use the file extension to distinguish header
files. Default is `true`.
.. title:: clang-tidy - misc-redundant-expression
misc-redundant-expression
=========================
Detect redundant expressions which are typically errors due to copy-paste.
Depending on the operator expressions may be
- redundant,
- always ``true``,
- always ``false``,
- always a constant (zero or one).
Examples:
.. code-block:: 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
.. title:: clang-tidy - misc-static-assert
misc-static-assert
==================
`cert-dcl03-c` redirects here as an alias for this check.
Replaces ``assert()`` with ``static_assert()`` if the condition is evaluatable
at compile time.
The condition of ``static_assert()`` is evaluated at compile time which is
safer and more efficient.
.. title:: clang-tidy - misc-uniqueptr-reset-release
misc-uniqueptr-reset-release
============================
Find and replace ``unique_ptr::reset(release())`` with ``std::move()``.
Example:
.. code-block:: c++
std::unique_ptr<Foo> x, y;
x.reset(y.release()); -> x = std::move(y);
If ``y`` is already rvalue, ``std::move()`` is not added. ``x`` and ``y`` can
also be ``std::unique_ptr<Foo>*``.
Options
-------
.. option:: IncludeStyle
A string specifying which include-style is used, `llvm` or `google`. Default
is `llvm`.
.. title:: clang-tidy - misc-unused-alias-decls
misc-unused-alias-decls
=======================
Finds unused namespace alias declarations.
.. code-block:: c++
namespace my_namespace {
class C {};
}
namespace unused_alias = ::my_namespace;
.. title:: clang-tidy - misc-unused-parameters
misc-unused-parameters
======================
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.
The check is similar to the ``-Wunused-parameter`` compiler diagnostic and can be
used to prepare a codebase to enabling of that diagnostic. By default the check
is more permissive (see :option:`StrictMode`).
.. code-block:: c++
void a(int i) { /*some code that doesn't use `i`*/ }
// becomes
void a(int /*i*/) { /*some code that doesn't use `i`*/ }
.. code-block:: c++
static void staticFunctionA(int i);
static void staticFunctionA(int i) { /*some code that doesn't use `i`*/ }
// becomes
static void staticFunctionA()
static void staticFunctionA() { /*some code that doesn't use `i`*/ }
Options
-------
.. option:: StrictMode
When `false` (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's basically no place for a bug to hide.
.. title:: clang-tidy - misc-unused-using-decls
misc-unused-using-decls
=======================
Finds unused ``using`` declarations.
Example:
.. code-block:: c++
namespace n { class C; }
using n::C; // Never actually used.
.. title:: clang-tidy - modernize-avoid-bind
modernize-avoid-bind
====================
The check finds uses of ``std::bind`` and ``boost::bind`` and replaces them
with lambdas. Lambdas will use value-capture unless reference capture is
explicitly requested with ``std::ref`` or ``boost::ref``.
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 ``bind`` 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.
Given:
.. code-block:: c++
int add(int x, int y) { return x + y; }
Then:
.. code-block:: c++
void f() {
int x = 2;
auto clj = std::bind(add, x, _1);
}
is replaced by:
.. code-block:: c++
void f() {
int x = 2;
auto clj = [=](auto && arg1) { return add(x, arg1); };
}
``std::bind`` 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.
Options
-------
.. option:: PermissiveParameterList
If the option is set to `true`, the check will append ``auto&&...`` 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 ``bind``
is used in the context of a type erased functor such as ``std::function`` which
allows mismatched arguments. For example:
.. code-block:: c++
int add(int x, int y) { return x + y; }
int foo() {
std::function<int(int,int)> ignore_args = std::bind(add, 2, 2);
return ignore_args(3, 3);
}
is valid code, and returns `4`. The actual values passed to ``ignore_args`` are
simply ignored. Without ``PermissiveParameterList``, this would be transformed into
.. code-block:: c++
int add(int x, int y) { return x + y; }
int foo() {
std::function<int(int,int)> ignore_args = [] { return add(2, 2); }
return ignore_args(3, 3);
}
which will *not* compile, since the lambda does not contain an ``operator()`` that
that accepts 2 arguments. With permissive parameter list, it instead generates
.. code-block:: c++
int add(int x, int y) { return x + y; }
int foo() {
std::function<int(int,int)> ignore_args = [](auto&&...) { return add(2, 2); }
return ignore_args(3, 3);
}
which is correct.
This check requires using C++14 or higher to run.
.. title:: clang-tidy - modernize-concat-nested-namespaces
modernize-concat-nested-namespaces
==================================
Checks for use of nested namespaces such as ``namespace a { namespace b { ... } }``
and suggests changing to the more concise syntax introduced in C++17: ``namespace a::b { ... }``.
Inline namespaces are not modified.
For example:
.. code-block:: c++
namespace n1 {
namespace n2 {
void t();
}
}
namespace n3 {
namespace n4 {
namespace n5 {
void t();
}
}
namespace n6 {
namespace n7 {
void t();
}
}
}
Will be modified to:
.. code-block:: c++
namespace n1::n2 {
void t();
}
namespace n3 {
namespace n4::n5 {
void t();
}
namespace n6::n7 {
void t();
}
}
.. title:: clang-tidy - modernize-deprecated-headers
modernize-deprecated-headers
============================
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.
This check replaces C standard library headers with their C++ alternatives and
removes redundant ones.
Important note: the Standard doesn't 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.
* `<assert.h>`
* `<complex.h>`
* `<ctype.h>`
* `<errno.h>`
* `<fenv.h>` // deprecated since C++11
* `<float.h>`
* `<inttypes.h>`
* `<limits.h>`
* `<locale.h>`
* `<math.h>`
* `<setjmp.h>`
* `<signal.h>`
* `<stdarg.h>`
* `<stddef.h>`
* `<stdint.h>`
* `<stdio.h>`
* `<stdlib.h>`
* `<string.h>`
* `<tgmath.h>` // deprecated since C++11
* `<time.h>`
* `<uchar.h>` // deprecated since C++11
* `<wchar.h>`
* `<wctype.h>`
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.
These headers don't have effect in C++:
* `<iso646.h>`
* `<stdalign.h>`
* `<stdbool.h>`
.. title:: clang-tidy - modernize-deprecated-ios-base-aliases
modernize-deprecated-ios-base-aliases
=====================================
Detects usage of the deprecated member types of ``std::ios_base`` and replaces
those that have a non-deprecated equivalent.
=================================== ===========================
Deprecated member type Replacement
=================================== ===========================
``std::ios_base::io_state`` ``std::ios_base::iostate``
``std::ios_base::open_mode`` ``std::ios_base::openmode``
``std::ios_base::seek_dir`` ``std::ios_base::seekdir``
``std::ios_base::streamoff``
``std::ios_base::streampos``
=================================== ===========================
.. title:: clang-tidy - modernize-loop-convert
modernize-loop-convert
======================
This check converts ``for(...; ...; ...)`` loops to use the new range-based
loops in C++11.
Three kinds of loops can be converted:
- Loops over statically allocated arrays.
- Loops over containers, using iterators.
- Loops over array-like containers, using ``operator[]`` and ``at()``.
MinConfidence option
--------------------
risky
^^^^^
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 `risky`, and thus will only
be converted if the minimum required confidence level is set to `risky`.
.. code-block:: 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 'obj' is considered risky
See
:ref:`Range-based loops evaluate end() only once<IncorrectRiskyTransformation>`
for an example of an incorrect transformation when the minimum required confidence
level is set to `risky`.
reasonable (Default)
^^^^^^^^^^^^^^^^^^^^
If a loop calls ``.end()`` or ``.size()`` after each iteration, the
transformation for that loop is marked as `reasonable`, and thus will
be converted if the required confidence level is set to `reasonable`
(default) or lower.
.. code-block:: c++
// using size() is considered reasonable
for (int i = 0; i < container.size(); ++i)
cout << container[i];
safe
^^^^
Any other loops that do not match the above criteria to be marked as
`risky` or `reasonable` are marked `safe`, and thus will be converted
if the required confidence level is set to `safe` or lower.
.. code-block:: c++
int arr[] = {1,2,3};
for (int i = 0; i < 3; ++i)
cout << arr[i];
Example
-------
Original:
.. code-block:: c++
const int N = 5;
int arr[] = {1,2,3,4,5};
vector<int> 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<int>::iterator it = v.begin(); it != v.end(); ++it)
cout << *it;
// reasonable conversion
for (int i = 0; i < v.size(); ++i)
cout << v[i];
After applying the check with minimum confidence level set to `reasonable` (default):
.. code-block:: c++
const int N = 5;
int arr[] = {1,2,3,4,5};
vector<int> 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;
Reverse Iterator Support
------------------------
The converter is also capable of transforming iterator loops which use
``rbegin`` and ``rend`` for looping backwards over a container. Out of the box
this will automatically happen in C++20 mode using the ``ranges`` 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.
.. option:: UseCxx20ReverseRanges
When set to true convert loops when in C++20 or later mode using
``std::ranges::reverse_view``.
Default value is ``true``.
.. option:: MakeReverseRangeFunction
Specify the function used to reverse an iterator pair, the function should
accept a class with ``rbegin`` and ``rend`` methods and return a
class with ``begin`` and ``end`` methods methods that call the ``rbegin`` and
``rend`` methods respectively. Common examples are ``ranges::reverse_view``
and ``llvm::reverse``.
Default value is an empty string.
.. option:: MakeReverseRangeHeader
Specifies the header file where :option:`MakeReverseRangeFunction` is
declared. For the previous examples this option would be set to
``range/v3/view/reverse.hpp`` and ``llvm/ADT/STLExtras.h`` respectively.
If this is an empty string and :option:`MakeReverseRangeFunction` 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.
.. option:: IncludeStyle
A string specifying which include-style is used, `llvm` or `google`. Default
is `llvm`.
Limitations
-----------
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 behaviour and limitations of the check outlined by
the cases below.
Comments inside loop headers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Comments inside the original loop header are ignored and deleted when
transformed.
.. code-block:: c++
for (int i = 0; i < N; /* This will be deleted */ ++i) { }
Range-based loops evaluate end() only once
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The C++11 range-based for loop calls ``.end()`` only once during the
initialization of the loop. If in the original loop ``.end()`` is called after
each iteration the semantics of the transformed loop may differ.
.. code-block:: 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) { }
.. _IncorrectRiskyTransformation:
As explained above, calling member functions of the container in the body
of the loop is considered `risky`. If the called member function modifies the
container the semantics of the converted loop will differ due to ``.end()``
being called only once.
.. code-block:: c++
bool flag = false;
for (vector<T>::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 'risky'.
vec.push_back(*it);
flag = true;
}
cout << *it;
}
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.
.. code-block:: 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 'risky'
vec.push_back(elem);
flag = true;
}
cout << elem;
}
Semantics will also be affected if ``.end()`` has side effects. For example, in
the case where calls to ``.end()`` are logged the semantics will change in the
transformed loop if ``.end()`` was originally called after each iteration.
.. code-block:: c++
iterator end() {
num_of_end_calls++;
return container.end();
}
Overloaded operator->() with side effects
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Similarly, if ``operator->()`` was overloaded to have side effects, such as
logging, the semantics will change. If the iterator's ``operator->()`` was used
in the original loop it will be replaced with ``<container element>.<member>``
instead due to the implicit dereference as part of the range-based for loop.
Therefore any side effect of the overloaded ``operator->()`` will no longer be
performed.
.. code-block:: 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->()
}
Pointers and references to containers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
While most of the check's 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.
If the container were directly used instead of using the pointer or reference
the following transformation would have only been applied at the `risky`
level since calling a member function of the container is considered `risky`.
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 `safe` level.
.. code-block:: c++
vector<int> vec;
vector<int> *ptr = &vec;
vector<int> &ref = vec;
for (vector<int>::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;
}
}
OpenMP
^^^^^^
As range-based for loops are only available since OpenMP 5, this check should
not been used on code with a compatibility requirements of OpenMP prior to
version 5. It is **intentional** that this check does not make any attempts to
exclude incorrect diagnostics on OpenMP for loops prior to OpenMP 5.
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 ``NOLINT`` (see
:ref:`clang-tidy-nolint`) on the specific for loops is recommended.
.. title:: clang-tidy - modernize-make-shared
modernize-make-shared
=====================
This check finds the creation of ``std::shared_ptr`` objects by explicitly
calling the constructor and a ``new`` expression, and replaces it with a call
to ``std::make_shared``.
.. code-block:: c++
auto my_ptr = std::shared_ptr<MyPair>(new MyPair(1, 2));
// becomes
auto my_ptr = std::make_shared<MyPair>(1, 2);
This check also finds calls to ``std::shared_ptr::reset()`` with a ``new``
expression, and replaces it with a call to ``std::make_shared``.
.. code-block:: c++
my_ptr.reset(new MyPair(1, 2));
// becomes
my_ptr = std::make_shared<MyPair>(1, 2);
Options
-------
.. option:: MakeSmartPtrFunction
A string specifying the name of make-shared-ptr function. Default is
`std::make_shared`.
.. option:: MakeSmartPtrFunctionHeader
A string specifying the corresponding header of make-shared-ptr function.
Default is `memory`.
.. option:: IncludeStyle
A string specifying which include-style is used, `llvm` or `google`. Default
is `llvm`.
.. option:: IgnoreMacros
If set to `true`, the check will not give warnings inside macros. Default
is `true`.
.. option:: 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 `1`.
.. title:: clang-tidy - modernize-make-unique
modernize-make-unique
=====================
This check finds the creation of ``std::unique_ptr`` objects by explicitly
calling the constructor and a ``new`` expression, and replaces it with a call
to ``std::make_unique``, introduced in C++14.
.. code-block:: c++
auto my_ptr = std::unique_ptr<MyPair>(new MyPair(1, 2));
// becomes
auto my_ptr = std::make_unique<MyPair>(1, 2);
This check also finds calls to ``std::unique_ptr::reset()`` with a ``new``
expression, and replaces it with a call to ``std::make_unique``.
.. code-block:: c++
my_ptr.reset(new MyPair(1, 2));
// becomes
my_ptr = std::make_unique<MyPair>(1, 2);
Options
-------
.. option:: MakeSmartPtrFunction
A string specifying the name of make-unique-ptr function. Default is
`std::make_unique`.
.. option:: MakeSmartPtrFunctionHeader
A string specifying the corresponding header of make-unique-ptr function.
Default is `<memory>`.
.. option:: IncludeStyle
A string specifying which include-style is used, `llvm` or `google`. Default
is `llvm`.
.. option:: IgnoreMacros
If set to `true`, the check will not give warnings inside macros. Default
is `true`.
.. option:: 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 `1`.
.. title:: clang-tidy - modernize-pass-by-value
modernize-pass-by-value
=======================
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.
The transformation is usually beneficial when the calling code passes an
*rvalue* and assumes the move construction is a cheap operation. This short
example illustrates how the construction of the value happens:
.. code-block:: 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
}
.. note::
Currently, only constructors are transformed to make use of pass-by-value.
Contributions that handle other situations are welcome!
Pass-by-value in constructors
-----------------------------
Replaces the uses of const-references constructor parameters that are copied
into class fields. The parameter is then moved with `std::move()`.
Since ``std::move()`` is a library function declared in `<utility>` it may be
necessary to add this include. The check will add the include directive when
necessary.
.. code-block:: c++
#include <string>
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 'get_cwd()' is move-constructed. By
// using pass-by-value in the Foo constructor we managed to avoid a
// copy-construction.
Foo foo(get_cwd(), Path);
}
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:
.. code-block:: c++
#include <string>
void pass(const std::string &S);
struct Foo {
Foo(const std::string &S) : Str(S) {
pass(S);
}
std::string Str;
};
Known limitations
^^^^^^^^^^^^^^^^^
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 "hidden" reference.
Example:
.. code-block:: c++
std::string s("foo");
struct Base {
Base() {
s = "bar";
}
};
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 "bar"
+ Derived d(s); // d.Field holds "foo"
}
Note about delayed template parsing
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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:
`Clang Compiler User’s Manual - Microsoft extensions`_.
Delayed template parsing can be enabled using the `-fdelayed-template-parsing`
flag and disabled using `-fno-delayed-template-parsing`.
Example:
.. code-block:: c++
template <typename T> 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)) {}
};
.. _Clang Compiler User’s Manual - Microsoft extensions: https://clang.llvm.org/docs/UsersManual.html#microsoft-extensions
.. seealso::
For more information about the pass-by-value idiom, read: `Want Speed? Pass by Value`_.
.. _Want Speed? Pass by Value: https://web.archive.org/web/20140205194657/http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
Options
-------
.. option:: IncludeStyle
A string specifying which include-style is used, `llvm` or `google`. Default
is `llvm`.
.. option:: ValuesOnly
When `true`, the check only warns about copied parameters that are already
passed by value. Default is `false`.
.. title:: clang-tidy - modernize-raw-string-literal
modernize-raw-string-literal
============================
This check selectively replaces string literals containing escaped characters
with raw string literals.
Example:
.. code-blocK:: c++
const char *const Quotes{"embedded \"quotes\""};
const char *const Paragraph{"Line one.\nLine two.\nLine three.\n"};
const char *const SingleLine{"Single line.\n"};
const char *const TrailingSpace{"Look here -> \n"};
const char *const Tab{"One\tTwo\n"};
const char *const Bell{"Hello!\a And welcome!"};
const char *const Path{"C:\\Program Files\\Vendor\\Application.exe"};
const char *const RegEx{"\\w\\([a-z]\\)"};
becomes
.. code-block:: c++
const char *const Quotes{R"(embedded "quotes")"};
const char *const Paragraph{"Line one.\nLine two.\nLine three.\n"};
const char *const SingleLine{"Single line.\n"};
const char *const TrailingSpace{"Look here -> \n"};
const char *const Tab{"One\tTwo\n"};
const char *const Bell{"Hello!\a And welcome!"};
const char *const Path{R"(C:\Program Files\Vendor\Application.exe)"};
const char *const RegEx{R"(\w\([a-z]\))"};
The presence of any of the following escapes can cause the string to be
converted to a raw string literal: ``\\``, ``\'``, ``\"``, ``\?``,
and octal or hexadecimal escapes for printable ASCII characters.
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.
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.
.. title:: clang-tidy - modernize-redundant-void-arg
modernize-redundant-void-arg
============================
Find and remove redundant ``void`` argument lists.
Examples:
=================================== ===========================
Initial code Code with applied fixes
=================================== ===========================
``int f(void);`` ``int f();``
``int (*f(void))(void);`` ``int (*f())();``
``typedef int (*f_t(void))(void);`` ``typedef int (*f_t())();``
``void (C::*p)(void);`` ``void (C::*p)();``
``C::C(void) {}`` ``C::C() {}``
``C::~C(void) {}`` ``C::~C() {}``
=================================== ===========================
.. title:: clang-tidy - modernize-replace-auto-ptr
modernize-replace-auto-ptr
==========================
This check replaces the uses of the deprecated class ``std::auto_ptr`` by
``std::unique_ptr`` (introduced in C++11). The transfer of ownership, done
by the copy-constructor and the assignment operator, is changed to match
``std::unique_ptr`` usage by using explicit calls to ``std::move()``.
Migration example:
.. code-block:: c++
-void take_ownership_fn(std::auto_ptr<int> int_ptr);
+void take_ownership_fn(std::unique_ptr<int> int_ptr);
void f(int x) {
- std::auto_ptr<int> a(new int(x));
- std::auto_ptr<int> b;
+ std::unique_ptr<int> a(new int(x));
+ std::unique_ptr<int> b;
- b = a;
- take_ownership_fn(b);
+ b = std::move(a);
+ take_ownership_fn(std::move(b));
}
Since ``std::move()`` is a library function declared in ``<utility>`` it may be
necessary to add this include. The check will add the include directive when
necessary.
Known Limitations
-----------------
* 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' code will stay unchanged while the code using them will be changed.
* Client code that declares a reference to an ``std::auto_ptr`` coming from
code that can't be migrated (such as a header coming from a 3\ :sup:`rd`
party library) will produce a compilation error after migration. This is
because the type of the reference will be changed to ``std::unique_ptr`` but
the type returned by the library won't change, binding a reference to
``std::unique_ptr`` from an ``std::auto_ptr``. This pattern doesn't make much
sense and usually ``std::auto_ptr`` are stored by value (otherwise what is
the point in using them instead of a reference or a pointer?).
.. code-block:: c++
// <3rd-party header...>
std::auto_ptr<int> get_value();
const std::auto_ptr<int> & get_ref();
// <calling code (with migration)...>
-std::auto_ptr<int> a(get_value());
+std::unique_ptr<int> a(get_value()); // ok, unique_ptr constructed from auto_ptr
-const std::auto_ptr<int> & p = get_ptr();
+const std::unique_ptr<int> & p = get_ptr(); // won't compile
* Non-instantiated templates aren't modified.
.. code-block:: c++
template <typename X>
void f() {
std::auto_ptr<X> p;
}
// only 'f<int>()' (or similar) will trigger the replacement.
Options
-------
.. option:: IncludeStyle
A string specifying which include-style is used, `llvm` or `google`. Default
is `llvm`.
.. title:: clang-tidy - modernize-replace-disallow-copy-and-assign-macro
modernize-replace-disallow-copy-and-assign-macro
================================================
Finds macro expansions of ``DISALLOW_COPY_AND_ASSIGN(Type)`` and replaces them
with a deleted copy constructor and a deleted assignment operator.
Before the ``delete`` keyword was introduced in C++11 it was common practice to
declare a copy constructor and an assignment operator as a private members. This
effectively makes them unusable to the public API of a class.
With the advent of the ``delete`` keyword in C++11 we can abandon the
``private`` access of the copy constructor and the assignment operator and
delete the methods entirely.
When running this check on a code like this:
.. code-block:: c++
class Foo {
private:
DISALLOW_COPY_AND_ASSIGN(Foo);
};
It will be transformed to this:
.. code-block:: c++
class Foo {
private:
Foo(const Foo &) = delete;
const Foo &operator=(const Foo &) = delete;
};
Known Limitations
-----------------
* Notice that the migration example above leaves the ``private`` access
specification untouched. You might want to run the check :doc:`modernize-use-equals-delete
<modernize-use-equals-delete>` to get warnings for deleted functions in
private sections.
Options
-------
.. option:: MacroName
A string specifying the macro name whose expansion will be replaced.
Default is `DISALLOW_COPY_AND_ASSIGN`.
See: https://en.cppreference.com/w/cpp/language/function#Deleted_functions
.. title:: clang-tidy - modernize-replace-random-shuffle
modernize-replace-random-shuffle
================================
This check will find occurrences of ``std::random_shuffle`` and replace it with ``std::shuffle``. In C++17 ``std::random_shuffle`` will no longer be available and thus we need to replace it.
Below are two examples of what kind of occurrences will be found and two examples of what it will be replaced with.
.. code-block:: c++
std::vector<int> v;
// First example
std::random_shuffle(vec.begin(), vec.end());
// Second example
std::random_shuffle(vec.begin(), vec.end(), randomFunc);
Both of these examples will be replaced with:
.. code-block:: c++
std::shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));
The second example will also receive a warning that ``randomFunc`` 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 ``randomFunc``.
One thing to be aware of here is that ``std::random_device`` 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: ``std::mt19937`` 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:
.. code-block:: c++
std::shuffle(v.begin(), v.end(), []() {
std::mt19937::result_type seeds[std::mt19937::state_size];
std::random_device device;
std::uniform_int_distribution<typename std::mt19937::result_type> 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);
}());
.. title:: clang-tidy - modernize-return-braced-init-list
modernize-return-braced-init-list
=================================
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.
.. code:: c++
Foo bar() {
Baz baz;
return Foo(baz);
}
// transforms to:
Foo bar() {
Baz baz;
return {baz};
}
.. title:: clang-tidy - modernize-shrink-to-fit
modernize-shrink-to-fit
=======================
Replace copy and swap tricks on shrinkable containers with the
``shrink_to_fit()`` method call.
The ``shrink_to_fit()`` method is more readable and more effective than
the copy and swap trick to reduce the capacity of a shrinkable container.
Note that, the ``shrink_to_fit()`` method is only available in C++11 and up.
.. title:: clang-tidy - modernize-unary-static-assert
modernize-unary-static-assert
=============================
The check diagnoses any ``static_assert`` declaration with an empty string literal
and provides a fix-it to replace the declaration with a single-argument ``static_assert`` declaration.
The check is only applicable for C++17 and later code.
The following code:
.. code-block:: c++
void f_textless(int a) {
static_assert(sizeof(a) <= 10, "");
}
is replaced by:
.. code-block:: c++
void f_textless(int a) {
static_assert(sizeof(a) <= 10);
}
.. title:: clang-tidy - modernize-use-auto
modernize-use-auto
==================
This check is responsible for using the ``auto`` type specifier for variable
declarations to *improve code readability and maintainability*. For example:
.. code-block:: c++
std::vector<int>::iterator I = my_container.begin();
// transforms to:
auto I = my_container.begin();
The ``auto`` type specifier will only be introduced in situations where the
variable type matches the type of the initializer expression. In other words
``auto`` should deduce the same type that was originally spelled in the source.
However, not every situation should be transformed:
.. code-block:: c++
int val = 42;
InfoStruct &I = SomeObject.getInfo();
// Should not become:
auto val = 42;
auto &I = SomeObject.getInfo();
In this example using ``auto`` for builtins doesn't improve readability. In
other situations it makes the code less self-documenting impairing readability
and maintainability. As a result, ``auto`` is used only introduced in specific
situations described below.
Iterators
---------
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.
.. code-block:: c++
for (std::vector<int>::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) {
}
The check will only replace iterator type-specifiers when all of the following
conditions are satisfied:
* The iterator is for one of the standard container in ``std`` namespace:
* ``array``
* ``deque``
* ``forward_list``
* ``list``
* ``vector``
* ``map``
* ``multimap``
* ``set``
* ``multiset``
* ``unordered_map``
* ``unordered_multimap``
* ``unordered_set``
* ``unordered_multiset``
* ``queue``
* ``priority_queue``
* ``stack``
* The iterator is one of the possible iterator types for standard containers:
* ``iterator``
* ``reverse_iterator``
* ``const_iterator``
* ``const_reverse_iterator``
* 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 ``std::vector<int>::iterator`` is itself a
typedef will not be transformed. Consider the following examples:
.. code-block:: c++
// The following direct uses of iterator types will be transformed.
std::vector<int>::iterator I = MyVec.begin();
{
using namespace std;
list<int>::iterator I = MyList.begin();
}
// The type specifier for J would transform to auto since it's a typedef
// to a standard iterator type.
typedef std::map<int, std::string>::const_iterator map_iterator;
map_iterator J = MyMap.begin();
// The following implementation-specific iterator type for which
// std::vector<int>::iterator could be a typedef would not be transformed.
__gnu_cxx::__normal_iterator<int*, std::vector> K = MyVec.begin();
* The initializer for the variable being declared is not a braced initializer
list. Otherwise, use of ``auto`` would cause the type of the variable to be
deduced as ``std::initializer_list``.
New expressions
---------------
Frequently, when a pointer is declared and initialized with ``new``, the
pointee type is written twice: in the declaration type and in the
``new`` expression. In this cases, the declaration type can be replaced with
``auto`` improving readability and maintainability.
.. code-block:: c++
TypeName *my_pointer = new TypeName(my_param);
// becomes
auto *my_pointer = new TypeName(my_param);
The check will also replace the declaration type in multiple declarations, if
the following conditions are satisfied:
* All declared variables have the same type (i.e. all of them are pointers to
the same type).
* All declared variables are initialized with a ``new`` expression.
* The types of all the new expressions are the same than the pointee of the
declaration type.
.. code-block:: c++
TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;
// becomes
auto *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;
Cast expressions
----------------
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 cases, the declaration type can be replaced with
``auto`` improving readability and maintainability.
.. code-block:: c++
TypeName *my_pointer = static_cast<TypeName>(my_param);
// becomes
auto *my_pointer = static_cast<TypeName>(my_param);
The check handles ``static_cast``, ``dynamic_cast``, ``const_cast``,
``reinterpret_cast``, functional casts, C-style casts and function templates
that behave as casts, such as ``llvm::dyn_cast``, ``boost::lexical_cast`` and
``gsl::narrow_cast``. 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.
Known Limitations
-----------------
* 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.
* User-defined iterators are not handled at this time.
Options
-------
.. option:: MinTypeNameLength
If the option is set to non-zero (default `5`), 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 (``long int``) are considered as one.
If the :option:`RemoveStars` option (see below) is set to `true`, then ``*s``
in the type are also counted as a part of the type name.
.. code-block:: c++
// MinTypeNameLength = 0, RemoveStars=0
int a = static_cast<int>(foo()); // ---> auto a = ...
// length(bool *) = 4
bool *b = new bool; // ---> auto *b = ...
unsigned c = static_cast<unsigned>(foo()); // ---> auto c = ...
// MinTypeNameLength = 5, RemoveStars=0
int a = static_cast<int>(foo()); // ---> int a = ...
bool b = static_cast<bool>(foo()); // ---> bool b = ...
bool *pb = static_cast<bool*>(foo()); // ---> bool *pb = ...
unsigned c = static_cast<unsigned>(foo()); // ---> auto c = ...
// length(long <on-or-more-spaces> int) = 8
long int d = static_cast<long int>(foo()); // ---> auto d = ...
// MinTypeNameLength = 5, RemoveStars=1
int a = static_cast<int>(foo()); // ---> int a = ...
// length(int * * ) = 5
int **pa = static_cast<int**>(foo()); // ---> auto pa = ...
bool b = static_cast<bool>(foo()); // ---> bool b = ...
bool *pb = static_cast<bool*>(foo()); // ---> auto pb = ...
unsigned c = static_cast<unsigned>(foo()); // ---> auto c = ...
long int d = static_cast<long int>(foo()); // ---> auto d = ...
.. option:: RemoveStars
If the option is set to `true` (default is `false`), the check will remove
stars from the non-typedef pointer types when replacing type names with
``auto``. Otherwise, the check will leave stars. For example:
.. code-block:: 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;
.. title:: clang-tidy - modernize-use-bool-literals
modernize-use-bool-literals
===========================
Finds integer literals which are cast to ``bool``.
.. code-block:: c++
bool p = 1;
bool f = static_cast<bool>(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;
Options
-------
.. option:: IgnoreMacros
If set to `true`, the check will not give warnings inside macros. Default
is `true`.
.. title:: clang-tidy - modernize-use-default-member-init
modernize-use-default-member-init
=================================
This check converts a default constructor's 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 '= default'.
.. code-block:: 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};
};
.. note::
Only converts member initializers for built-in types, enums, and pointers.
The `readability-redundant-member-init` check will remove redundant member
initializers for classes.
Options
-------
.. option:: UseAssignment
If this option is set to `true` (default is `false`), the check will initialise
members with an assignment. For example:
.. code-block:: c++
struct A {
A() {}
A(int i) : i(i) {}
int i = 5;
double j = 10.0;
};
.. option:: IgnoreMacros
If this option is set to `true` (default is `true`), the check will not warn
about members declared inside macros.
.. title:: clang-tidy - modernize-use-emplace
modernize-use-emplace
=====================
The check flags insertions to an STL-style container done by calling the
``push_back`` method with an explicitly-constructed temporary of the container
element type. In this case, the corresponding ``emplace_back`` method
results in less verbose and potentially more efficient code.
Right now the check doesn't support ``push_front`` and ``insert``.
It also doesn't support ``insert`` functions for associative containers
because replacing ``insert`` with ``emplace`` may result in
`speed regression <https://htmlpreview.github.io/?https://github.com/HowardHinnant/papers/blob/master/insert_vs_emplace.html>`_, but it might get support with some addition flag in the future.
By default only ``std::vector``, ``std::deque``, ``std::list`` are considered.
This list can be modified using the :option:`ContainersWithPushBack` option.
Before:
.. code-block:: c++
std::vector<MyClass> v;
v.push_back(MyClass(21, 37));
std::vector<std::pair<int, int>> w;
w.push_back(std::pair<int, int>(21, 37));
w.push_back(std::make_pair(21L, 37L));
After:
.. code-block:: c++
std::vector<MyClass> v;
v.emplace_back(21, 37);
std::vector<std::pair<int, int>> w;
w.emplace_back(21, 37);
w.emplace_back(21L, 37L);
By default, the check is able to remove unnecessary ``std::make_pair`` and
``std::make_tuple`` calls from ``push_back`` calls on containers of
``std::pair`` and ``std::tuple``. Custom tuple-like types can be modified by
the :option:`TupleTypes` option; custom make functions can be modified by the
:option:`TupleMakeFunctions` option.
The other situation is when we pass arguments that will be converted to a type
inside a container.
Before:
.. code-block:: c++
std::vector<boost::optional<std::string> > v;
v.push_back("abc");
After:
.. code-block:: c++
std::vector<boost::optional<std::string> > v;
v.emplace_back("abc");
In some cases the transformation would be valid, but the code wouldn't be
exception safe. In this case the calls of ``push_back`` won't be replaced.
.. code-block:: c++
std::vector<std::unique_ptr<int>> v;
v.push_back(std::unique_ptr<int>(new int(0)));
auto *ptr = new int(1);
v.push_back(std::unique_ptr<int>(ptr));
This is because replacing it with ``emplace_back`` could cause a leak of this
pointer if ``emplace_back`` would throw exception before emplacement (e.g. not
enough memory to add a new element).
For more info read item 42 - "Consider emplacement instead of insertion." of
Scott Meyers "Effective Modern C++".
The default smart pointers that are considered are ``std::unique_ptr``,
``std::shared_ptr``, ``std::auto_ptr``. To specify other smart pointers or
other classes use the :option:`SmartPointers` option.
Check also doesn't fire if any argument of the constructor call would be:
- a bit-field (bit-fields can't bind to rvalue/universal reference)
- a ``new`` expression (to avoid leak)
- if the argument would be converted via derived-to-base cast.
This check requires C++11 or higher to run.
Options
-------
.. option:: ContainersWithPushBack
Semicolon-separated list of class names of custom containers that support
``push_back``.
.. option:: IgnoreImplicitConstructors
When `true`, the check will ignore implicitly constructed arguments of
``push_back``, e.g.
.. code-block:: c++
std::vector<std::string> v;
v.push_back("a"); // Ignored when IgnoreImplicitConstructors is `true`.
Default is `false`.
.. option:: SmartPointers
Semicolon-separated list of class names of custom smart pointers.
.. option:: TupleTypes
Semicolon-separated list of ``std::tuple``-like class names.
.. option:: TupleMakeFunctions
Semicolon-separated list of ``std::make_tuple``-like function names. Those
function calls will be removed from ``push_back`` calls and turned into
``emplace_back``.
Example
^^^^^^^
.. code-block:: c++
std::vector<MyTuple<int, bool, char>> x;
x.push_back(MakeMyTuple(1, false, 'x'));
transforms to:
.. code-block:: c++
std::vector<MyTuple<int, bool, char>> x;
x.emplace_back(1, false, 'x');
when :option:`TupleTypes` is set to ``MyTuple`` and :option:`TupleMakeFunctions`
is set to ``MakeMyTuple``.
.. title:: clang-tidy - modernize-use-equals-default
modernize-use-equals-default
============================
This check replaces default bodies of special member functions with ``=
default;``. The explicitly defaulted function declarations enable more
opportunities in optimization, because the compiler might treat explicitly
defaulted functions as trivial.
.. code-block:: c++
struct A {
A() {}
~A();
};
A::~A() {}
// becomes
struct A {
A() = default;
~A();
};
A::~A() = default;
.. note::
Move-constructor and move-assignment operator are not supported yet.
Options
-------
.. option:: IgnoreMacros
If set to `true`, the check will not give warnings inside macros. Default
is `true`.
.. title:: clang-tidy - modernize-use-equals-delete
modernize-use-equals-delete
===========================
This check marks unimplemented private special member functions with ``= delete``.
To avoid false-positives, this check only applies in a translation unit that has
all other member functions implemented.
.. code-block:: c++
struct A {
private:
A(const A&);
A& operator=(const A&);
};
// becomes
struct A {
private:
A(const A&) = delete;
A& operator=(const A&) = delete;
};
.. option:: IgnoreMacros
If this option is set to `true` (default is `true`), the check will not warn
about functions declared inside macros.
.. title:: clang-tidy - modernize-use-nodiscard
modernize-use-nodiscard
=======================
Adds ``[[nodiscard]]`` attributes (introduced in C++17) to member functions in
order to highlight at compile time which return values should not be ignored.
Member functions need to satisfy the following conditions to be considered by
this check:
- no ``[[nodiscard]]``, ``[[noreturn]]``,
``__attribute__((warn_unused_result))``,
``[[clang::warn_unused_result]]`` nor ``[[gcc::warn_unused_result]]``
attribute,
- non-void return type,
- non-template return types,
- const member function,
- non-variadic functions,
- no non-const reference parameters,
- no pointer parameters,
- no template parameters,
- no template function parameters,
- not be a member of a class with mutable member variables,
- no Lambdas,
- no conversion functions.
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).
Example
-------
.. code-block:: c++
bool empty() const;
bool empty(int i) const;
transforms to:
.. code-block:: c++
[[nodiscard]] bool empty() const;
[[nodiscard]] bool empty(int i) const;
Options
-------
.. option:: ReplacementString
Specifies a macro to use instead of ``[[nodiscard]]``. This is useful when
maintaining source code that needs to compile with a pre-C++17 compiler.
Example
^^^^^^^
.. code-block:: c++
bool empty() const;
bool empty(int i) const;
transforms to:
.. code-block:: c++
NO_DISCARD bool empty() const;
NO_DISCARD bool empty(int i) const;
if the :option:`ReplacementString` option is set to `NO_DISCARD`.
.. note::
If the :option:`ReplacementString` 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.
.. note::
For alternative ``__attribute__`` syntax options to mark functions as
``[[nodiscard]]`` in non-c++17 source code.
See https://clang.llvm.org/docs/AttributeReference.html#nodiscard-warn-unused-result
.. title:: clang-tidy - modernize-use-noexcept
modernize-use-noexcept
======================
This check replaces deprecated dynamic exception specifications with
the appropriate noexcept specification (introduced in C++11). By
default this check will replace ``throw()`` with ``noexcept``,
and ``throw(<exception>[,...])`` or ``throw(...)`` with
``noexcept(false)``.
Example
-------
.. code-block:: c++
void foo() throw();
void bar() throw(int) {}
transforms to:
.. code-block:: c++
void foo() noexcept;
void bar() noexcept(false) {}
Options
-------
.. option:: ReplacementString
Users can use :option:`ReplacementString` to specify a macro to use
instead of ``noexcept``. This is useful when maintaining source code
that uses custom exception specification marking other than
``noexcept``. Fix-it hints will only be generated for non-throwing
specifications.
Example
^^^^^^^
.. code-block:: c++
void bar() throw(int);
void foo() throw();
transforms to:
.. code-block:: c++
void bar() throw(int); // No fix-it generated.
void foo() NOEXCEPT;
if the :option:`ReplacementString` option is set to `NOEXCEPT`.
.. option:: UseNoexceptFalse
Enabled by default, disabling will generate fix-it hints that remove
throwing dynamic exception specs, e.g., ``throw(<something>)``,
completely without providing a replacement text, except for
destructors and delete operators that are ``noexcept(true)`` by
default.
Example
^^^^^^^
.. code-block:: 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);
}
transforms to:
.. code-block:: c++
void foo() {}
struct bar {
void foobar();
void operator delete(void *ptr) noexcept(false);
void operator delete[](void *ptr) noexcept(false);
~bar() noexcept(false);
}
if the :option:`UseNoexceptFalse` option is set to `false`.
.. title:: clang-tidy - modernize-use-nullptr
modernize-use-nullptr
=====================
The check converts the usage of null pointer constants (eg. ``NULL``, ``0``)
to use the new C++11 ``nullptr`` keyword.
Example
-------
.. code-block:: c++
void assignment() {
char *a = NULL;
char *b = 0;
char c = 0;
}
int *ret_ptr() {
return 0;
}
transforms to:
.. code-block:: c++
void assignment() {
char *a = nullptr;
char *b = nullptr;
char c = 0;
}
int *ret_ptr() {
return nullptr;
}
Options
-------
.. option:: NullMacros
Comma-separated list of macro names that will be transformed along with
``NULL``. By default this check will only replace the ``NULL`` macro and will
skip any similar user-defined macros.
Example
^^^^^^^
.. code-block:: c++
#define MY_NULL (void*)0
void assignment() {
void *p = MY_NULL;
}
transforms to:
.. code-block:: c++
#define MY_NULL NULL
void assignment() {
int *p = nullptr;
}
if the :option:`NullMacros` option is set to ``MY_NULL``.
.. title:: clang-tidy - modernize-use-override
modernize-use-override
======================
Adds ``override`` (introduced in C++11) to overridden virtual functions and
removes ``virtual`` from those functions as it is not required.
``virtual`` 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.
In C++ 11 ``override`` and ``final`` 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.
This can be useful as compilers can generate a compile time error when:
- The base class implementation function signature changes.
- The user has not created the override with the correct signature.
Options
-------
.. option:: IgnoreDestructors
If set to `true`, this check will not diagnose destructors. Default is `false`.
.. option:: AllowOverrideAndFinal
If set to `true`, this check will not diagnose ``override`` as redundant
with ``final``. This is useful when code will be compiled by a compiler with
warning/error checking flags requiring ``override`` explicitly on overridden
members, such as ``gcc -Wsuggest-override``/``gcc -Werror=suggest-override``.
Default is `false`.
.. option:: OverrideSpelling
Specifies a macro to use instead of ``override``. This is useful when
maintaining source code that also needs to compile with a pre-C++11
compiler.
.. option:: FinalSpelling
Specifies a macro to use instead of ``final``. This is useful when
maintaining source code that also needs to compile with a pre-C++11
compiler.
.. note::
For more information on the use of ``override`` see https://en.cppreference.com/w/cpp/language/override
.. title:: clang-tidy - modernize-use-trailing-return-type
modernize-use-trailing-return-type
==================================
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 ``auto``
and inserted after the function parameter list (and qualifiers).
Example
-------
.. code-block:: c++
int f1();
inline int f2(int arg) noexcept;
virtual float f3() const && = delete;
transforms to:
.. code-block:: c++
auto f1() -> int;
inline auto f2(int arg) -> int noexcept;
virtual auto f3() const && -> float = delete;
Known Limitations
-----------------
The following categories of return types cannot be rewritten currently:
* function pointers
* member function pointers
* member pointers
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.
Given the following piece of code
.. code-block:: 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}; }
a careless rewrite would produce the following output:
.. code-block:: 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
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.
.. title:: clang-tidy - modernize-use-transparent-functors
modernize-use-transparent-functors
==================================
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.
.. code-block:: c++
// Non-transparent functor
std::map<int, std::string, std::greater<int>> s;
// Transparent functor.
std::map<int, std::string, std::greater<>> s;
// Non-transparent functor
using MyFunctor = std::less<MyType>;
It is not always a safe transformation though. The following case will be
untouched to preserve the semantics.
.. code-block:: c++
// Non-transparent functor
std::map<const char *, std::string, std::greater<std::string>> s;
Options
-------
.. option:: SafeMode
If the option is set to `true`, 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 `false`.
This check requires using C++14 or higher to run.
.. title:: clang-tidy - modernize-use-uncaught-exceptions
modernize-use-uncaught-exceptions
====================================
This check will warn on calls to ``std::uncaught_exception`` and replace them
with calls to ``std::uncaught_exceptions``, since ``std::uncaught_exception``
was deprecated in C++17.
Below are a few examples of what kind of occurrences will be found and what
they will be replaced with.
.. code-block:: 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
}
After applying the fixes the code will look like the following:
.. code-block:: 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();
}
.. title:: clang-tidy - modernize-use-using
modernize-use-using
===================
The check converts the usage of ``typedef`` with ``using`` keyword.
Before:
.. code-block:: c++
typedef int variable;
class Class{};
typedef void (Class::* MyPtrType)() const;
typedef struct { int a; } R_t, *R_p;
After:
.. code-block:: c++
using variable = int;
class Class{};
using MyPtrType = void (Class::*)() const;
using R_t = struct { int a; };
using R_p = R_t*;
This check requires using C++11 or higher to run.
Options
-------
.. option:: IgnoreMacros
If set to `true`, the check will not give warnings inside macros. Default
is `true`.
.. title:: clang-tidy - mpi-buffer-deref
mpi-buffer-deref
================
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 ``void *`` for their buffer
types, insufficiently dereferenced buffers can be passed, like for example as
double pointers or multidimensional arrays, without a compiler warning emitted.
Examples:
.. code-block:: 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);
.. title:: clang-tidy - mpi-type-mismatch
mpi-type-mismatch
=================
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.
Example:
.. code-block:: 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);
.. title:: clang-tidy - objc-nsinvocation-argument-lifetime
objc-nsinvocation-argument-lifetime
===================================
Finds calls to ``NSInvocation`` methods under ARC that don't have proper
argument object lifetimes. When passing Objective-C objects as parameters
to the ``NSInvocation`` methods ``getArgument:atIndex:`` and
``getReturnValue:``, the values are copied by value into the argument pointer,
which leads to to incorrect releasing behavior if the object pointers are
not declared ``__unsafe_unretained``.
For code:
.. code-block:: objc
id arg;
[invocation getArgument:&arg atIndex:2];
__strong id returnValue;
[invocation getReturnValue:&returnValue];
The fix will be:
.. code-block:: objc
__unsafe_unretained id arg;
[invocation getArgument:&arg atIndex:2];
__unsafe_unretained id returnValue;
[invocation getReturnValue:&returnValue];
The check will warn on being passed instance variable references that have
lifetimes other than ``__unsafe_unretained``, but does not propose a fix:
.. code-block:: objc
// "id _returnValue" is declaration of instance variable of class.
[invocation getReturnValue:&self->_returnValue];
.. title:: clang-tidy - objc-property-declaration
objc-property-declaration
=========================
Finds property declarations in Objective-C files that do not follow the pattern
of property names in Apple's programming guide. The property name should be
in the format of Lower Camel Case.
For code:
.. code-block:: objc
@property(nonatomic, assign) int LowerCamelCase;
The fix will be:
.. code-block:: objc
@property(nonatomic, assign) int lowerCamelCase;
The check will only fix 'CamelCase' to 'camelCase'. 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.
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:
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingBasics.html#//apple_ref/doc/uid/20001281-1002931-BBCFHEAB
For a full list of well-known acronyms:
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/APIAbbreviations.html#//apple_ref/doc/uid/20001285-BCIHCGAE
The corresponding style rule: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingIvarsAndTypes.html#//apple_ref/doc/uid/20001284-1001757
The check will also accept property declared in category with a prefix of
lowercase letters followed by a '_' to avoid naming conflict. For example:
.. code-block:: objc
@property(nonatomic, assign) int abc_lowerCamelCase;
The corresponding style rule: https://developer.apple.com/library/content/qa/qa1908/_index.html
.. title:: clang-tidy - objc-super-self
objc-super-self
===============
Finds invocations of ``-self`` on super instances in initializers of subclasses
of ``NSObject`` and recommends calling a superclass initializer instead.
Invoking ``-self`` on super instances in initializers is a common programmer
error when the programmer's original intent is to call a superclass
initializer. Failing to call a superclass initializer breaks initializer
chaining and can result in invalid object initialization.
.. title:: clang-tidy - performance-faster-string-find
performance-faster-string-find
==============================
Optimize calls to ``std::string::find()`` and friends when the needle passed is
a single character string literal. The character literal overload is more
efficient.
Examples:
.. code-block:: c++
str.find("A");
// becomes
str.find('A');
Options
-------
.. option:: StringLikeClasses
Semicolon-separated list of names of string-like classes. By default only
``::std::basic_string`` and ``::std::basic_string_view`` are considered.
The check will only consider member functions named ``find``, ``rfind``,
``find_first_of``, ``find_first_not_of``, ``find_last_of``, or
``find_last_not_of`` within these classes.
.. title:: clang-tidy - performance-for-range-copy
performance-for-range-copy
==========================
Finds C++11 for ranges where the loop variable is copied in each iteration but
it would suffice to obtain it by const reference.
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.
To ensure that it is safe to replace the copy with a const reference the
following heuristic is employed:
1. The loop variable is const qualified.
2. 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.
Options
-------
.. option:: WarnOnAllAutoCopies
When `true`, warns on any use of `auto` as the type of the range-based for
loop variable. Default is `false`.
.. option:: AllowedTypes
A semicolon-separated list of names of types allowed to be copied in each
iteration. Regular expressions are accepted, e.g. `[Rr]ef(erence)?$` matches
every type with suffix `Ref`, `ref`, `Reference` and `reference`. The default
is empty. If a name in the list contains the sequence `::` it is matched
against the qualified typename (i.e. `namespace::Type`, otherwise it is
matched against only the type name (i.e. `Type`).
.. title:: clang-tidy - performance-inefficient-algorithm
performance-inefficient-algorithm
=================================
Warns on inefficient use of STL algorithms on associative containers.
Associative containers implements 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.
.. code-block:: c++
std::set<int> s;
auto it = std::find(s.begin(), s.end(), 43);
// becomes
auto it = s.find(43);
.. code-block:: c++
std::set<int> s;
auto c = std::count(s.begin(), s.end(), 43);
// becomes
auto c = s.count(43);
.. title:: clang-tidy - performance-inefficient-vector-operation
performance-inefficient-vector-operation
========================================
Finds possible inefficient ``std::vector`` operations (e.g. ``push_back``,
``emplace_back``) that may cause unnecessary memory reallocations.
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.
Currently, the check only detects following kinds of loops with a single
statement body:
* Counter-based for loops start with 0:
.. code-block:: c++
std::vector<int> 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 'reserve(n)'
// 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
// 'p.mutable_xxx().Reserve(n)' statement before the for statement.
}
* For-range loops like ``for (range-declaration : range_expression)``, the type
of ``range_expression`` can be ``std::vector``, ``std::array``,
``std::deque``, ``std::set``, ``std::unordered_set``, ``std::map``,
``std::unordered_set``:
.. code-block:: c++
std::vector<int> data;
std::vector<int> v;
for (auto element : data) {
v.push_back(element);
// This will trigger the warning since the 'push_back' may cause multiple
// memory reallocations in v. This can be avoid by inserting a
// 'reserve(data.size())' statement before the for statement.
}
Options
-------
.. option:: VectorLikeClasses
Semicolon-separated list of names of vector-like classes. By default only
``::std::vector`` is considered.
.. option:: EnableProto
When `true`, the check will also warn on inefficient operations for proto
repeated fields. Otherwise, the check only warns on inefficient vector
operations. Default is `false`.
.. title:: clang-tidy - performance-move-const-arg
performance-move-const-arg
==========================
The check warns
- if ``std::move()`` is called with a constant argument,
- if ``std::move()`` is called with an argument of a trivially-copyable type,
- if the result of ``std::move()`` is passed as a const reference argument.
In all three cases, the check will suggest a fix that removes the
``std::move()``.
Here are examples of each of the three cases:
.. code-block:: 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
Options
-------
.. option:: CheckTriviallyCopyableMove
If `true`, enables detection of trivially copyable types that do not
have a move constructor. Default is `true`.
.. title:: clang-tidy - performance-noexcept-move-constructor
performance-noexcept-move-constructor
=====================================
The check flags user-defined move constructors and assignment operators not
marked with ``noexcept`` or marked with ``noexcept(expr)`` where ``expr``
evaluates to ``false`` (but is not a ``false`` literal itself).
Move constructors of all the types used with STL containers, for example,
need to be declared ``noexcept``. Otherwise STL will choose copy constructors
instead. The same is valid for move assignment operations.
.. title:: clang-tidy - performance-trivially-destructible
performance-trivially-destructible
==================================
Finds types that could be made trivially-destructible by removing out-of-line
defaulted destructor declarations.
.. code-block:: c++
struct A: TrivialType {
~A(); // Makes A non-trivially-destructible.
TrivialType trivial_fields;
};
A::~A() = default;
.. title:: clang-tidy - performance-type-promotion-in-math-fn
performance-type-promotion-in-math-fn
=====================================
Finds calls to C math library functions (from ``math.h`` or, in C++, ``cmath``)
with implicit ``float`` to ``double`` promotions.
For example, warns on ``::sin(0.f)``, because this funciton's parameter is a
double. You probably meant to call ``std::sin(0.f)`` (in C++), or ``sinf(0.f)``
(in C).
.. code-block:: c++
float a;
asin(a);
// becomes
float a;
std::asin(a);
.. title:: clang-tidy - performance-unnecessary-value-param
performance-unnecessary-value-param
===================================
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.
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.
To ensure that it is safe to replace the value parameter with a const reference
the following heuristic is employed:
1. the parameter is const qualified;
2. 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.
Example:
.. code-block:: 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);
}
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.
Example:
.. code-block:: c++
void setValue(string Value) {
Field = Value;
}
Will become:
.. code-block:: c++
#include <utility>
void setValue(string Value) {
Field = std::move(Value);
}
Options
-------
.. option:: IncludeStyle
A string specifying which include-style is used, `llvm` or `google`. Default
is `llvm`.
.. option:: AllowedTypes
A semicolon-separated list of names of types allowed to be passed by value.
Regular expressions are accepted, e.g. `[Rr]ef(erence)?$` matches every type
with suffix `Ref`, `ref`, `Reference` and `reference`. The default is
empty. If a name in the list contains the sequence `::` it is matched against
the qualified typename (i.e. `namespace::Type`, otherwise it is matched
against only the type name (i.e. `Type`).
.. title:: clang-tidy - portability-restrict-system-includes
portability-restrict-system-includes
====================================
Checks to selectively allow or disallow a configurable list of system headers.
For example:
In order to **only** allow `zlib.h` from the system you would set the options
to `-*,zlib.h`.
.. code-block:: c++
#include <curses.h> // Bad: disallowed system header.
#include <openssl/ssl.h> // Bad: disallowed system header.
#include <zlib.h> // Good: allowed system header.
#include "src/myfile.h" // Good: non-system header always allowed.
In order to allow everything **except** `zlib.h` from the system you would set
the options to `*,-zlib.h`.
.. code-block:: c++
#include <curses.h> // Good: allowed system header.
#include <openssl/ssl.h> // Good: allowed system header.
#include <zlib.h> // Bad: disallowed system header.
#include "src/myfile.h" // Good: non-system header always allowed.
Since the options support globbing you can use wildcarding to allow groups of
headers.
`-*,openssl/*.h` will allow all openssl headers but disallow any others.
.. code-block:: c++
#include <curses.h> // Bad: disallowed system header.
#include <openssl/ssl.h> // Good: allowed system header.
#include <openssl/rsa.h> // Good: allowed system header.
#include <zlib.h> // Bad: disallowed system header.
#include "src/myfile.h" // Good: non-system header always allowed.
Options
-------
.. option:: 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 `*` and `-`, to include and exclude globs,
respectively. The default is `*`, which allows all includes.
.. title:: clang-tidy - readability-braces-around-statements
readability-braces-around-statements
====================================
`google-readability-braces-around-statements` redirects here as an alias for
this check.
Checks that bodies of ``if`` statements and loops (``for``, ``do while``, and
``while``) are inside braces.
Before:
.. code-block:: c++
if (condition)
statement;
After:
.. code-block:: c++
if (condition) {
statement;
}
Options
-------
.. option:: ShortStatementLines
Defines the minimal number of lines that the statement should have in order
to trigger this check.
The number of lines is counted from the end of condition or initial keyword
(``do``/``else``) until the last line of the inner statement. Default value
`0` means that braces will be added to all statements (not having them
already).
.. title:: clang-tidy - readability-const-return-type
readability-const-return-type
=============================
Checks for functions with a ``const``-qualified return type and recommends
removal of the ``const`` keyword. Such use of `const` is usually superfluous,
and can prevent valuable compiler optimizations. Does not (yet) fix trailing
return types.
Examples:
.. code-block:: c++
const int foo();
const Clazz foo();
Clazz *const foo();
Note that this applies strictly to top-level qualification, which excludes
pointers or references to const values. For example, these are fine:
.. code-block:: c++
const int* foo();
const int& foo();
const Clazz* foo();
.. title:: clang-tidy - readability-container-size-empty
readability-container-size-empty
================================
Checks whether a call to the ``size()`` method can be replaced with a call to
``empty()``.
The emptiness of a container should be checked using the ``empty()`` method
instead of the ``size()`` method. It is not guaranteed that ``size()`` is a
constant-time function, and it is generally more efficient and also shows
clearer intent to use ``empty()``. Furthermore some containers may implement
the ``empty()`` method but not implement the ``size()`` method. Using
``empty()`` whenever possible makes it easier to switch to another container in
the future.
The check issues warning if a container has ``size()`` and ``empty()`` methods
matching following signatures:
.. code-block:: c++
size_type size() const;
bool empty() const;
`size_type` can be any kind of integer type.
.. title:: clang-tidy - readability-delete-null-pointer
readability-delete-null-pointer
===============================
Checks the ``if`` statements where a pointer's existence is checked and then deletes the pointer.
The check is unnecessary as deleting a null pointer has no effect.
.. code:: c++
int *p;
if (p)
delete p;
.. title:: clang-tidy - readability-else-after-return
readability-else-after-return
=============================
`LLVM Coding Standards <https://llvm.org/docs/CodingStandards.html>`_ 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
``else`` or ``else if`` after something that interrupts control flow - like
``return``, ``break``, ``continue``, ``throw``.
The following piece of code illustrates how the check works. This piece of code:
.. code-block:: 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++;
}
}
}
Would be transformed into:
.. code-block:: 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++;
}
}
Options
-------
.. option:: WarnOnUnfixable
When `true`, emit a warning for cases where the check can't output a
Fix-It. These can occur with declarations inside the ``else`` branch that
would have an extended lifetime if the ``else`` branch was removed.
Default value is `true`.
.. option:: WarnOnConditionVariables
When `true`, the check will attempt to refactor a variable defined inside
the condition of the ``if`` statement that is used in the ``else`` branch
defining them just before the ``if`` statement. This can only be done if
the ``if`` statement is the last statement in its parents scope.
Default value is `true`.
LLVM alias
----------
There is an alias of this check called llvm-else-after-return.
In that version the options :option:`WarnOnUnfixable` and
:option:`WarnOnConditionVariables` are both set to `false` by default.
This check helps to enforce this `LLVM Coding Standards recommendation
<https://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return>`_.
.. title:: clang-tidy - readability-identifier-naming
readability-identifier-naming
=============================
Checks for identifiers naming style mismatch.
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
Casing types include:
- ``lower_case``,
- ``UPPER_CASE``,
- ``camelBack``,
- ``CamelCase``,
- ``camel_Snake_Back``,
- ``Camel_Snake_Case``,
- ``aNy_CasE``.
It also supports a fixed prefix and suffix that will be prepended or appended
to the identifiers, regardless of the casing.
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.
The naming of virtual methods is reported where they occur in the base class,
but not where they are overridden, as it can't be fixed locally there.
This also applies for pseudo-override patterns like CRTP.
Options
-------
The following options are describe below:
- :option:`AbstractClassCase`, :option:`AbstractClassPrefix`, :option:`AbstractClassSuffix`, :option:`AbstractClassIgnoredRegexp`
- :option:`AggressiveDependentMemberLookup`
- :option:`ClassCase`, :option:`ClassPrefix`, :option:`ClassSuffix`, :option:`ClassIgnoredRegexp`
- :option:`ClassConstantCase`, :option:`ClassConstantPrefix`, :option:`ClassConstantSuffix`, :option:`ClassConstantIgnoredRegexp`
- :option:`ClassMemberCase`, :option:`ClassMemberPrefix`, :option:`ClassMemberSuffix`, :option:`ClassMemberIgnoredRegexp`
- :option:`ClassMethodCase`, :option:`ClassMethodPrefix`, :option:`ClassMethodSuffix`, :option:`ClassMethodIgnoredRegexp`
- :option:`ConstantCase`, :option:`ConstantPrefix`, :option:`ConstantSuffix`, :option:`ConstantIgnoredRegexp`
- :option:`ConstantMemberCase`, :option:`ConstantMemberPrefix`, :option:`ConstantMemberSuffix`, :option:`ConstantMemberIgnoredRegexp`
- :option:`ConstantParameterCase`, :option:`ConstantParameterPrefix`, :option:`ConstantParameterSuffix`, :option:`ConstantParameterIgnoredRegexp`
- :option:`ConstantPointerParameterCase`, :option:`ConstantPointerParameterPrefix`, :option:`ConstantPointerParameterSuffix`, :option:`ConstantPointerParameterIgnoredRegexp`
- :option:`ConstexprFunctionCase`, :option:`ConstexprFunctionPrefix`, :option:`ConstexprFunctionSuffix`, :option:`ConstexprFunctionIgnoredRegexp`
- :option:`ConstexprMethodCase`, :option:`ConstexprMethodPrefix`, :option:`ConstexprMethodSuffix`, :option:`ConstexprMethodIgnoredRegexp`
- :option:`ConstexprVariableCase`, :option:`ConstexprVariablePrefix`, :option:`ConstexprVariableSuffix`, :option:`ConstexprVariableIgnoredRegexp`
- :option:`EnumCase`, :option:`EnumPrefix`, :option:`EnumSuffix`, :option:`EnumIgnoredRegexp`
- :option:`EnumConstantCase`, :option:`EnumConstantPrefix`, :option:`EnumConstantSuffix`, :option:`EnumConstantIgnoredRegexp`
- :option:`FunctionCase`, :option:`FunctionPrefix`, :option:`FunctionSuffix`, :option:`FunctionIgnoredRegexp`
- :option:`GetConfigPerFile`
- :option:`GlobalConstantCase`, :option:`GlobalConstantPrefix`, :option:`GlobalConstantSuffix`, :option:`GlobalConstantIgnoredRegexp`
- :option:`GlobalConstantPointerCase`, :option:`GlobalConstantPointerPrefix`, :option:`GlobalConstantPointerSuffix`, :option:`GlobalConstantPointerIgnoredRegexp`
- :option:`GlobalFunctionCase`, :option:`GlobalFunctionPrefix`, :option:`GlobalFunctionSuffix`, :option:`GlobalFunctionIgnoredRegexp`
- :option:`GlobalPointerCase`, :option:`GlobalPointerPrefix`, :option:`GlobalPointerSuffix`, :option:`GlobalPointerIgnoredRegexp`
- :option:`GlobalVariableCase`, :option:`GlobalVariablePrefix`, :option:`GlobalVariableSuffix`, :option:`GlobalVariableIgnoredRegexp`
- :option:`IgnoreMainLikeFunctions`
- :option:`InlineNamespaceCase`, :option:`InlineNamespacePrefix`, :option:`InlineNamespaceSuffix`, :option:`InlineNamespaceIgnoredRegexp`
- :option:`LocalConstantCase`, :option:`LocalConstantPrefix`, :option:`LocalConstantSuffix`, :option:`LocalConstantIgnoredRegexp`
- :option:`LocalConstantPointerCase`, :option:`LocalConstantPointerPrefix`, :option:`LocalConstantPointerSuffix`, :option:`LocalConstantPointerIgnoredRegexp`
- :option:`LocalPointerCase`, :option:`LocalPointerPrefix`, :option:`LocalPointerSuffix`, :option:`LocalPointerIgnoredRegexp`
- :option:`LocalVariableCase`, :option:`LocalVariablePrefix`, :option:`LocalVariableSuffix`, :option:`LocalVariableIgnoredRegexp`
- :option:`MacroDefinitionCase`, :option:`MacroDefinitionPrefix`, :option:`MacroDefinitionSuffix`, :option:`MacroDefinitionIgnoredRegexp`
- :option:`MemberCase`, :option:`MemberPrefix`, :option:`MemberSuffix`, :option:`MemberIgnoredRegexp`
- :option:`MethodCase`, :option:`MethodPrefix`, :option:`MethodSuffix`, :option:`MethodIgnoredRegexp`
- :option:`NamespaceCase`, :option:`NamespacePrefix`, :option:`NamespaceSuffix`, :option:`NamespaceIgnoredRegexp`
- :option:`ParameterCase`, :option:`ParameterPrefix`, :option:`ParameterSuffix`, :option:`ParameterIgnoredRegexp`
- :option:`ParameterPackCase`, :option:`ParameterPackPrefix`, :option:`ParameterPackSuffix`, :option:`ParameterPackIgnoredRegexp`
- :option:`PointerParameterCase`, :option:`PointerParameterPrefix`, :option:`PointerParameterSuffix`, :option:`PointerParameterIgnoredRegexp`
- :option:`PrivateMemberCase`, :option:`PrivateMemberPrefix`, :option:`PrivateMemberSuffix`, :option:`PrivateMemberIgnoredRegexp`
- :option:`PrivateMethodCase`, :option:`PrivateMethodPrefix`, :option:`PrivateMethodSuffix`, :option:`PrivateMethodIgnoredRegexp`
- :option:`ProtectedMemberCase`, :option:`ProtectedMemberPrefix`, :option:`ProtectedMemberSuffix`, :option:`ProtectedMemberIgnoredRegexp`
- :option:`ProtectedMethodCase`, :option:`ProtectedMethodPrefix`, :option:`ProtectedMethodSuffix`, :option:`ProtectedMethodIgnoredRegexp`
- :option:`PublicMemberCase`, :option:`PublicMemberPrefix`, :option:`PublicMemberSuffix`, :option:`PublicMemberIgnoredRegexp`
- :option:`PublicMethodCase`, :option:`PublicMethodPrefix`, :option:`PublicMethodSuffix`, :option:`PublicMethodIgnoredRegexp`
- :option:`ScopedEnumConstantCase`, :option:`ScopedEnumConstantPrefix`, :option:`ScopedEnumConstantSuffix`, :option:`ScopedEnumConstantIgnoredRegexp`
- :option:`StaticConstantCase`, :option:`StaticConstantPrefix`, :option:`StaticConstantSuffix`, :option:`StaticConstantIgnoredRegexp`
- :option:`StaticVariableCase`, :option:`StaticVariablePrefix`, :option:`StaticVariableSuffix`, :option:`StaticVariableIgnoredRegexp`
- :option:`StructCase`, :option:`StructPrefix`, :option:`StructSuffix`, :option:`StructIgnoredRegexp`
- :option:`TemplateParameterCase`, :option:`TemplateParameterPrefix`, :option:`TemplateParameterSuffix`, :option:`TemplateParameterIgnoredRegexp`
- :option:`TemplateTemplateParameterCase`, :option:`TemplateTemplateParameterPrefix`, :option:`TemplateTemplateParameterSuffix`, :option:`TemplateTemplateParameterIgnoredRegexp`
- :option:`TypeAliasCase`, :option:`TypeAliasPrefix`, :option:`TypeAliasSuffix`, :option:`TypeAliasIgnoredRegexp`
- :option:`TypedefCase`, :option:`TypedefPrefix`, :option:`TypedefSuffix`, :option:`TypedefIgnoredRegexp`
- :option:`TypeTemplateParameterCase`, :option:`TypeTemplateParameterPrefix`, :option:`TypeTemplateParameterSuffix`, :option:`TypeTemplateParameterIgnoredRegexp`
- :option:`UnionCase`, :option:`UnionPrefix`, :option:`UnionSuffix`, :option:`UnionIgnoredRegexp`
- :option:`ValueTemplateParameterCase`, :option:`ValueTemplateParameterPrefix`, :option:`ValueTemplateParameterSuffix`, :option:`ValueTemplateParameterIgnoredRegexp`
- :option:`VariableCase`, :option:`VariablePrefix`, :option:`VariableSuffix`, :option:`VariableIgnoredRegexp`
- :option:`VirtualMethodCase`, :option:`VirtualMethodPrefix`, :option:`VirtualMethodSuffix`, :option:`VirtualMethodIgnoredRegexp`
.. option:: AbstractClassCase
When defined, the check will ensure abstract class names conform to the
selected casing.
.. option:: AbstractClassPrefix
When defined, the check will ensure abstract class names will add the
prefixed with the given value (regardless of casing).
.. option:: AbstractClassIgnoredRegexp
Identifier naming checks won't be enforced for abstract class names
matching this regular expression.
.. option:: AbstractClassSuffix
When defined, the check will ensure abstract class names will add the
suffix with the given value (regardless of casing).
For example using values of:
- AbstractClassCase of ``lower_case``
- AbstractClassPrefix of ``pre_``
- AbstractClassSuffix of ``_post``
Identifies and/or transforms abstract class names as follows:
Before:
.. code-block:: c++
class ABSTRACT_CLASS {
public:
ABSTRACT_CLASS();
};
After:
.. code-block:: c++
class pre_abstract_class_post {
public:
pre_abstract_class_post();
};
.. option:: AggressiveDependentMemberLookup
When set to `true` 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 `false`.
For example using values of:
- ClassMemberCase of ``lower_case``
Before:
.. code-block:: c++
template <typename T>
struct Base {
T BadNamedMember;
};
template <typename T>
struct Derived : Base<T> {
void reset() {
this->BadNamedMember = 0;
}
};
After if AggressiveDependentMemberLookup is `false`:
.. code-block:: c++
template <typename T>
struct Base {
T bad_named_member;
};
template <typename T>
struct Derived : Base<T> {
void reset() {
this->BadNamedMember = 0;
}
};
After if AggressiveDependentMemberLookup is `true`:
.. code-block:: c++
template <typename T>
struct Base {
T bad_named_member;
};
template <typename T>
struct Derived : Base<T> {
void reset() {
this->bad_named_member = 0;
}
};
.. option:: ClassCase
When defined, the check will ensure class names conform to the
selected casing.
.. option:: ClassPrefix
When defined, the check will ensure class names will add the
prefixed with the given value (regardless of casing).
.. option:: ClassIgnoredRegexp
Identifier naming checks won't be enforced for class names matching
this regular expression.
.. option:: ClassSuffix
When defined, the check will ensure class names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ClassCase of ``lower_case``
- ClassPrefix of ``pre_``
- ClassSuffix of ``_post``
Identifies and/or transforms class names as follows:
Before:
.. code-block:: c++
class FOO {
public:
FOO();
~FOO();
};
After:
.. code-block:: c++
class pre_foo_post {
public:
pre_foo_post();
~pre_foo_post();
};
.. option:: ClassConstantCase
When defined, the check will ensure class constant names conform to the
selected casing.
.. option:: ClassConstantPrefix
When defined, the check will ensure class constant names will add the
prefixed with the given value (regardless of casing).
.. option:: ClassConstantIgnoredRegexp
Identifier naming checks won't be enforced for class constant names
matching this regular expression.
.. option:: ClassConstantSuffix
When defined, the check will ensure class constant names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ClassConstantCase of ``lower_case``
- ClassConstantPrefix of ``pre_``
- ClassConstantSuffix of ``_post``
Identifies and/or transforms class constant names as follows:
Before:
.. code-block:: c++
class FOO {
public:
static const int CLASS_CONSTANT;
};
After:
.. code-block:: c++
class FOO {
public:
static const int pre_class_constant_post;
};
.. option:: ClassMemberCase
When defined, the check will ensure class member names conform to the
selected casing.
.. option:: ClassMemberPrefix
When defined, the check will ensure class member names will add the
prefixed with the given value (regardless of casing).
.. option:: ClassMemberIgnoredRegexp
Identifier naming checks won't be enforced for class member names
matching this regular expression.
.. option:: ClassMemberSuffix
When defined, the check will ensure class member names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ClassMemberCase of ``lower_case``
- ClassMemberPrefix of ``pre_``
- ClassMemberSuffix of ``_post``
Identifies and/or transforms class member names as follows:
Before:
.. code-block:: c++
class FOO {
public:
static int CLASS_CONSTANT;
};
After:
.. code-block:: c++
class FOO {
public:
static int pre_class_constant_post;
};
.. option:: ClassMethodCase
When defined, the check will ensure class method names conform to the
selected casing.
.. option:: ClassMethodPrefix
When defined, the check will ensure class method names will add the
prefixed with the given value (regardless of casing).
.. option:: ClassMethodIgnoredRegexp
Identifier naming checks won't be enforced for class method names
matching this regular expression.
.. option:: ClassMethodSuffix
When defined, the check will ensure class method names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ClassMethodCase of ``lower_case``
- ClassMethodPrefix of ``pre_``
- ClassMethodSuffix of ``_post``
Identifies and/or transforms class method names as follows:
Before:
.. code-block:: c++
class FOO {
public:
int CLASS_MEMBER();
};
After:
.. code-block:: c++
class FOO {
public:
int pre_class_member_post();
};
.. option:: ConstantCase
When defined, the check will ensure constant names conform to the
selected casing.
.. option:: ConstantPrefix
When defined, the check will ensure constant names will add the
prefixed with the given value (regardless of casing).
.. option:: ConstantIgnoredRegexp
Identifier naming checks won't be enforced for constant names
matching this regular expression.
.. option:: ConstantSuffix
When defined, the check will ensure constant names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ConstantCase of ``lower_case``
- ConstantPrefix of ``pre_``
- ConstantSuffix of ``_post``
Identifies and/or transforms constant names as follows:
Before:
.. code-block:: c++
void function() { unsigned const MyConst_array[] = {1, 2, 3}; }
After:
.. code-block:: c++
void function() { unsigned const pre_myconst_array_post[] = {1, 2, 3}; }
.. option:: ConstantMemberCase
When defined, the check will ensure constant member names conform to the
selected casing.
.. option:: ConstantMemberPrefix
When defined, the check will ensure constant member names will add the
prefixed with the given value (regardless of casing).
.. option:: ConstantMemberIgnoredRegexp
Identifier naming checks won't be enforced for constant member names
matching this regular expression.
.. option:: ConstantMemberSuffix
When defined, the check will ensure constant member names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ConstantMemberCase of ``lower_case``
- ConstantMemberPrefix of ``pre_``
- ConstantMemberSuffix of ``_post``
Identifies and/or transforms constant member names as follows:
Before:
.. code-block:: c++
class Foo {
char const MY_ConstMember_string[4] = "123";
}
After:
.. code-block:: c++
class Foo {
char const pre_my_constmember_string_post[4] = "123";
}
.. option:: ConstantParameterCase
When defined, the check will ensure constant parameter names conform to the
selected casing.
.. option:: ConstantParameterPrefix
When defined, the check will ensure constant parameter names will add the
prefixed with the given value (regardless of casing).
.. option:: ConstantParameterIgnoredRegexp
Identifier naming checks won't be enforced for constant parameter names
matching this regular expression.
.. option:: ConstantParameterSuffix
When defined, the check will ensure constant parameter names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ConstantParameterCase of ``lower_case``
- ConstantParameterPrefix of ``pre_``
- ConstantParameterSuffix of ``_post``
Identifies and/or transforms constant parameter names as follows:
Before:
.. code-block:: c++
void GLOBAL_FUNCTION(int PARAMETER_1, int const CONST_parameter);
After:
.. code-block:: c++
void GLOBAL_FUNCTION(int PARAMETER_1, int const pre_const_parameter_post);
.. option:: ConstantPointerParameterCase
When defined, the check will ensure constant pointer parameter names conform to the
selected casing.
.. option:: ConstantPointerParameterPrefix
When defined, the check will ensure constant pointer parameter names will add the
prefixed with the given value (regardless of casing).
.. option:: ConstantPointerParameterIgnoredRegexp
Identifier naming checks won't be enforced for constant pointer parameter
names matching this regular expression.
.. option:: ConstantPointerParameterSuffix
When defined, the check will ensure constant pointer parameter names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ConstantPointerParameterCase of ``lower_case``
- ConstantPointerParameterPrefix of ``pre_``
- ConstantPointerParameterSuffix of ``_post``
Identifies and/or transforms constant pointer parameter names as follows:
Before:
.. code-block:: c++
void GLOBAL_FUNCTION(int const *CONST_parameter);
After:
.. code-block:: c++
void GLOBAL_FUNCTION(int const *pre_const_parameter_post);
.. option:: ConstexprFunctionCase
When defined, the check will ensure constexpr function names conform to the
selected casing.
.. option:: ConstexprFunctionPrefix
When defined, the check will ensure constexpr function names will add the
prefixed with the given value (regardless of casing).
.. option:: ConstexprFunctionIgnoredRegexp
Identifier naming checks won't be enforced for constexpr function names
matching this regular expression.
.. option:: ConstexprFunctionSuffix
When defined, the check will ensure constexpr function names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ConstexprFunctionCase of ``lower_case``
- ConstexprFunctionPrefix of ``pre_``
- ConstexprFunctionSuffix of ``_post``
Identifies and/or transforms constexpr function names as follows:
Before:
.. code-block:: c++
constexpr int CE_function() { return 3; }
After:
.. code-block:: c++
constexpr int pre_ce_function_post() { return 3; }
.. option:: ConstexprMethodCase
When defined, the check will ensure constexpr method names conform to the
selected casing.
.. option:: ConstexprMethodPrefix
When defined, the check will ensure constexpr method names will add the
prefixed with the given value (regardless of casing).
.. option:: ConstexprMethodIgnoredRegexp
Identifier naming checks won't be enforced for constexpr method names
matching this regular expression.
.. option:: ConstexprMethodSuffix
When defined, the check will ensure constexpr method names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ConstexprMethodCase of ``lower_case``
- ConstexprMethodPrefix of ``pre_``
- ConstexprMethodSuffix of ``_post``
Identifies and/or transforms constexpr method names as follows:
Before:
.. code-block:: c++
class Foo {
public:
constexpr int CST_expr_Method() { return 2; }
}
After:
.. code-block:: c++
class Foo {
public:
constexpr int pre_cst_expr_method_post() { return 2; }
}
.. option:: ConstexprVariableCase
When defined, the check will ensure constexpr variable names conform to the
selected casing.
.. option:: ConstexprVariablePrefix
When defined, the check will ensure constexpr variable names will add the
prefixed with the given value (regardless of casing).
.. option:: ConstexprVariableIgnoredRegexp
Identifier naming checks won't be enforced for constexpr variable names
matching this regular expression.
.. option:: ConstexprVariableSuffix
When defined, the check will ensure constexpr variable names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ConstexprVariableCase of ``lower_case``
- ConstexprVariablePrefix of ``pre_``
- ConstexprVariableSuffix of ``_post``
Identifies and/or transforms constexpr variable names as follows:
Before:
.. code-block:: c++
constexpr int ConstExpr_variable = MyConstant;
After:
.. code-block:: c++
constexpr int pre_constexpr_variable_post = MyConstant;
.. option:: EnumCase
When defined, the check will ensure enumeration names conform to the
selected casing.
.. option:: EnumPrefix
When defined, the check will ensure enumeration names will add the
prefixed with the given value (regardless of casing).
.. option:: EnumIgnoredRegexp
Identifier naming checks won't be enforced for enumeration names
matching this regular expression.
.. option:: EnumSuffix
When defined, the check will ensure enumeration names will add the
suffix with the given value (regardless of casing).
For example using values of:
- EnumCase of ``lower_case``
- EnumPrefix of ``pre_``
- EnumSuffix of ``_post``
Identifies and/or transforms enumeration names as follows:
Before:
.. code-block:: c++
enum FOO { One, Two, Three };
After:
.. code-block:: c++
enum pre_foo_post { One, Two, Three };
.. option:: EnumConstantCase
When defined, the check will ensure enumeration constant names conform to the
selected casing.
.. option:: EnumConstantPrefix
When defined, the check will ensure enumeration constant names will add the
prefixed with the given value (regardless of casing).
.. option:: EnumConstantIgnoredRegexp
Identifier naming checks won't be enforced for enumeration constant names
matching this regular expression.
.. option:: EnumConstantSuffix
When defined, the check will ensure enumeration constant names will add the
suffix with the given value (regardless of casing).
For example using values of:
- EnumConstantCase of ``lower_case``
- EnumConstantPrefix of ``pre_``
- EnumConstantSuffix of ``_post``
Identifies and/or transforms enumeration constant names as follows:
Before:
.. code-block:: c++
enum FOO { One, Two, Three };
After:
.. code-block:: c++
enum FOO { pre_One_post, pre_Two_post, pre_Three_post };
.. option:: FunctionCase
When defined, the check will ensure function names conform to the
selected casing.
.. option:: FunctionPrefix
When defined, the check will ensure function names will add the
prefixed with the given value (regardless of casing).
.. option:: FunctionIgnoredRegexp
Identifier naming checks won't be enforced for function names
matching this regular expression.
.. option:: FunctionSuffix
When defined, the check will ensure function names will add the
suffix with the given value (regardless of casing).
For example using values of:
- FunctionCase of ``lower_case``
- FunctionPrefix of ``pre_``
- FunctionSuffix of ``_post``
Identifies and/or transforms function names as follows:
Before:
.. code-block:: c++
char MY_Function_string();
After:
.. code-block:: c++
char pre_my_function_string_post();
.. option:: GetConfigPerFile
When `true` 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 `true`.
.. option:: GlobalConstantCase
When defined, the check will ensure global constant names conform to the
selected casing.
.. option:: GlobalConstantPrefix
When defined, the check will ensure global constant names will add the
prefixed with the given value (regardless of casing).
.. option:: GlobalConstantIgnoredRegexp
Identifier naming checks won't be enforced for global constant names
matching this regular expression.
.. option:: GlobalConstantSuffix
When defined, the check will ensure global constant names will add the
suffix with the given value (regardless of casing).
For example using values of:
- GlobalConstantCase of ``lower_case``
- GlobalConstantPrefix of ``pre_``
- GlobalConstantSuffix of ``_post``
Identifies and/or transforms global constant names as follows:
Before:
.. code-block:: c++
unsigned const MyConstGlobal_array[] = {1, 2, 3};
After:
.. code-block:: c++
unsigned const pre_myconstglobal_array_post[] = {1, 2, 3};
.. option:: GlobalConstantPointerCase
When defined, the check will ensure global constant pointer names conform to the
selected casing.
.. option:: GlobalConstantPointerPrefix
When defined, the check will ensure global constant pointer names will add the
prefixed with the given value (regardless of casing).
.. option:: GlobalConstantPointerIgnoredRegexp
Identifier naming checks won't be enforced for global constant pointer
names matching this regular expression.
.. option:: GlobalConstantPointerSuffix
When defined, the check will ensure global constant pointer names will add the
suffix with the given value (regardless of casing).
For example using values of:
- GlobalConstantPointerCase of ``lower_case``
- GlobalConstantPointerPrefix of ``pre_``
- GlobalConstantPointerSuffix of ``_post``
Identifies and/or transforms global constant pointer names as follows:
Before:
.. code-block:: c++
int *const MyConstantGlobalPointer = nullptr;
After:
.. code-block:: c++
int *const pre_myconstantglobalpointer_post = nullptr;
.. option:: GlobalFunctionCase
When defined, the check will ensure global function names conform to the
selected casing.
.. option:: GlobalFunctionPrefix
When defined, the check will ensure global function names will add the
prefixed with the given value (regardless of casing).
.. option:: GlobalFunctionIgnoredRegexp
Identifier naming checks won't be enforced for global function names
matching this regular expression.
.. option:: GlobalFunctionSuffix
When defined, the check will ensure global function names will add the
suffix with the given value (regardless of casing).
For example using values of:
- GlobalFunctionCase of ``lower_case``
- GlobalFunctionPrefix of ``pre_``
- GlobalFunctionSuffix of ``_post``
Identifies and/or transforms global function names as follows:
Before:
.. code-block:: c++
void GLOBAL_FUNCTION(int PARAMETER_1, int const CONST_parameter);
After:
.. code-block:: c++
void pre_global_function_post(int PARAMETER_1, int const CONST_parameter);
.. option:: GlobalPointerCase
When defined, the check will ensure global pointer names conform to the
selected casing.
.. option:: GlobalPointerPrefix
When defined, the check will ensure global pointer names will add the
prefixed with the given value (regardless of casing).
.. option:: GlobalPointerIgnoredRegexp
Identifier naming checks won't be enforced for global pointer names
matching this regular expression.
.. option:: GlobalPointerSuffix
When defined, the check will ensure global pointer names will add the
suffix with the given value (regardless of casing).
For example using values of:
- GlobalPointerCase of ``lower_case``
- GlobalPointerPrefix of ``pre_``
- GlobalPointerSuffix of ``_post``
Identifies and/or transforms global pointer names as follows:
Before:
.. code-block:: c++
int *GLOBAL3;
After:
.. code-block:: c++
int *pre_global3_post;
.. option:: GlobalVariableCase
When defined, the check will ensure global variable names conform to the
selected casing.
.. option:: GlobalVariablePrefix
When defined, the check will ensure global variable names will add the
prefixed with the given value (regardless of casing).
.. option:: GlobalVariableIgnoredRegexp
Identifier naming checks won't be enforced for global variable names
matching this regular expression.
.. option:: GlobalVariableSuffix
When defined, the check will ensure global variable names will add the
suffix with the given value (regardless of casing).
For example using values of:
- GlobalVariableCase of ``lower_case``
- GlobalVariablePrefix of ``pre_``
- GlobalVariableSuffix of ``_post``
Identifies and/or transforms global variable names as follows:
Before:
.. code-block:: c++
int GLOBAL3;
After:
.. code-block:: c++
int pre_global3_post;
.. option:: IgnoreMainLikeFunctions
When set to `true` functions that have a similar signature to ``main`` or
``wmain`` won't enforce checks on the names of their parameters.
Default value is `false`.
.. option:: InlineNamespaceCase
When defined, the check will ensure inline namespaces names conform to the
selected casing.
.. option:: InlineNamespacePrefix
When defined, the check will ensure inline namespaces names will add the
prefixed with the given value (regardless of casing).
.. option:: InlineNamespaceIgnoredRegexp
Identifier naming checks won't be enforced for inline namespaces names
matching this regular expression.
.. option:: InlineNamespaceSuffix
When defined, the check will ensure inline namespaces names will add the
suffix with the given value (regardless of casing).
For example using values of:
- InlineNamespaceCase of ``lower_case``
- InlineNamespacePrefix of ``pre_``
- InlineNamespaceSuffix of ``_post``
Identifies and/or transforms inline namespaces names as follows:
Before:
.. code-block:: c++
namespace FOO_NS {
inline namespace InlineNamespace {
...
}
} // namespace FOO_NS
After:
.. code-block:: c++
namespace FOO_NS {
inline namespace pre_inlinenamespace_post {
...
}
} // namespace FOO_NS
.. option:: LocalConstantCase
When defined, the check will ensure local constant names conform to the
selected casing.
.. option:: LocalConstantPrefix
When defined, the check will ensure local constant names will add the
prefixed with the given value (regardless of casing).
.. option:: LocalConstantIgnoredRegexp
Identifier naming checks won't be enforced for local constant names
matching this regular expression.
.. option:: LocalConstantSuffix
When defined, the check will ensure local constant names will add the
suffix with the given value (regardless of casing).
For example using values of:
- LocalConstantCase of ``lower_case``
- LocalConstantPrefix of ``pre_``
- LocalConstantSuffix of ``_post``
Identifies and/or transforms local constant names as follows:
Before:
.. code-block:: c++
void foo() { int const local_Constant = 3; }
After:
.. code-block:: c++
void foo() { int const pre_local_constant_post = 3; }
.. option:: LocalConstantPointerCase
When defined, the check will ensure local constant pointer names conform to the
selected casing.
.. option:: LocalConstantPointerPrefix
When defined, the check will ensure local constant pointer names will add the
prefixed with the given value (regardless of casing).
.. option:: LocalConstantPointerIgnoredRegexp
Identifier naming checks won't be enforced for local constant pointer names
matching this regular expression.
.. option:: LocalConstantPointerSuffix
When defined, the check will ensure local constant pointer names will add the
suffix with the given value (regardless of casing).
For example using values of:
- LocalConstantPointerCase of ``lower_case``
- LocalConstantPointerPrefix of ``pre_``
- LocalConstantPointerSuffix of ``_post``
Identifies and/or transforms local constant pointer names as follows:
Before:
.. code-block:: c++
void foo() { int const *local_Constant = 3; }
After:
.. code-block:: c++
void foo() { int const *pre_local_constant_post = 3; }
.. option:: LocalPointerCase
When defined, the check will ensure local pointer names conform to the
selected casing.
.. option:: LocalPointerPrefix
When defined, the check will ensure local pointer names will add the
prefixed with the given value (regardless of casing).
.. option:: LocalPointerIgnoredRegexp
Identifier naming checks won't be enforced for local pointer names
matching this regular expression.
.. option:: LocalPointerSuffix
When defined, the check will ensure local pointer names will add the
suffix with the given value (regardless of casing).
For example using values of:
- LocalPointerCase of ``lower_case``
- LocalPointerPrefix of ``pre_``
- LocalPointerSuffix of ``_post``
Identifies and/or transforms local pointer names as follows:
Before:
.. code-block:: c++
void foo() { int *local_Constant; }
After:
.. code-block:: c++
void foo() { int *pre_local_constant_post; }
.. option:: LocalVariableCase
When defined, the check will ensure local variable names conform to the
selected casing.
.. option:: LocalVariablePrefix
When defined, the check will ensure local variable names will add the
prefixed with the given value (regardless of casing).
.. option:: LocalVariableIgnoredRegexp
Identifier naming checks won't be enforced for local variable names
matching this regular expression.
For example using values of:
- LocalVariableCase of ``CamelCase``
- LocalVariableIgnoredRegexp of ``\w{1,2}``
Will exclude variables with a length less than or equal to 2 from the
camel case check applied to other variables.
.. option:: LocalVariableSuffix
When defined, the check will ensure local variable names will add the
suffix with the given value (regardless of casing).
For example using values of:
- LocalVariableCase of ``lower_case``
- LocalVariablePrefix of ``pre_``
- LocalVariableSuffix of ``_post``
Identifies and/or transforms local variable names as follows:
Before:
.. code-block:: c++
void foo() { int local_Constant; }
After:
.. code-block:: c++
void foo() { int pre_local_constant_post; }
.. option:: MacroDefinitionCase
When defined, the check will ensure macro definitions conform to the
selected casing.
.. option:: MacroDefinitionPrefix
When defined, the check will ensure macro definitions will add the
prefixed with the given value (regardless of casing).
.. option:: MacroDefinitionIgnoredRegexp
Identifier naming checks won't be enforced for macro definitions
matching this regular expression.
.. option:: MacroDefinitionSuffix
When defined, the check will ensure macro definitions will add the
suffix with the given value (regardless of casing).
For example using values of:
- MacroDefinitionCase of ``lower_case``
- MacroDefinitionPrefix of ``pre_``
- MacroDefinitionSuffix of ``_post``
Identifies and/or transforms macro definitions as follows:
Before:
.. code-block:: c
#define MY_MacroDefinition
After:
.. code-block:: c
#define pre_my_macro_definition_post
Note: This will not warn on builtin macros or macros defined on the command line
using the ``-D`` flag.
.. option:: MemberCase
When defined, the check will ensure member names conform to the
selected casing.
.. option:: MemberPrefix
When defined, the check will ensure member names will add the
prefixed with the given value (regardless of casing).
.. option:: MemberIgnoredRegexp
Identifier naming checks won't be enforced for member names
matching this regular expression.
.. option:: MemberSuffix
When defined, the check will ensure member names will add the
suffix with the given value (regardless of casing).
For example using values of:
- MemberCase of ``lower_case``
- MemberPrefix of ``pre_``
- MemberSuffix of ``_post``
Identifies and/or transforms member names as follows:
Before:
.. code-block:: c++
class Foo {
char MY_ConstMember_string[4];
}
After:
.. code-block:: c++
class Foo {
char pre_my_constmember_string_post[4];
}
.. option:: MethodCase
When defined, the check will ensure method names conform to the
selected casing.
.. option:: MethodPrefix
When defined, the check will ensure method names will add the
prefixed with the given value (regardless of casing).
.. option:: MethodIgnoredRegexp
Identifier naming checks won't be enforced for method names
matching this regular expression.
.. option:: MethodSuffix
When defined, the check will ensure method names will add the
suffix with the given value (regardless of casing).
For example using values of:
- MethodCase of ``lower_case``
- MethodPrefix of ``pre_``
- MethodSuffix of ``_post``
Identifies and/or transforms method names as follows:
Before:
.. code-block:: c++
class Foo {
char MY_Method_string();
}
After:
.. code-block:: c++
class Foo {
char pre_my_method_string_post();
}
.. option:: NamespaceCase
When defined, the check will ensure namespace names conform to the
selected casing.
.. option:: NamespacePrefix
When defined, the check will ensure namespace names will add the
prefixed with the given value (regardless of casing).
.. option:: NamespaceIgnoredRegexp
Identifier naming checks won't be enforced for namespace names
matching this regular expression.
.. option:: NamespaceSuffix
When defined, the check will ensure namespace names will add the
suffix with the given value (regardless of casing).
For example using values of:
- NamespaceCase of ``lower_case``
- NamespacePrefix of ``pre_``
- NamespaceSuffix of ``_post``
Identifies and/or transforms namespace names as follows:
Before:
.. code-block:: c++
namespace FOO_NS {
...
}
After:
.. code-block:: c++
namespace pre_foo_ns_post {
...
}
.. option:: ParameterCase
When defined, the check will ensure parameter names conform to the
selected casing.
.. option:: ParameterPrefix
When defined, the check will ensure parameter names will add the
prefixed with the given value (regardless of casing).
.. option:: ParameterIgnoredRegexp
Identifier naming checks won't be enforced for parameter names
matching this regular expression.
.. option:: ParameterSuffix
When defined, the check will ensure parameter names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ParameterCase of ``lower_case``
- ParameterPrefix of ``pre_``
- ParameterSuffix of ``_post``
Identifies and/or transforms parameter names as follows:
Before:
.. code-block:: c++
void GLOBAL_FUNCTION(int PARAMETER_1, int const CONST_parameter);
After:
.. code-block:: c++
void GLOBAL_FUNCTION(int pre_parameter_post, int const CONST_parameter);
.. option:: ParameterPackCase
When defined, the check will ensure parameter pack names conform to the
selected casing.
.. option:: ParameterPackPrefix
When defined, the check will ensure parameter pack names will add the
prefixed with the given value (regardless of casing).
.. option:: ParameterPackIgnoredRegexp
Identifier naming checks won't be enforced for parameter pack names
matching this regular expression.
.. option:: ParameterPackSuffix
When defined, the check will ensure parameter pack names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ParameterPackCase of ``lower_case``
- ParameterPackPrefix of ``pre_``
- ParameterPackSuffix of ``_post``
Identifies and/or transforms parameter pack names as follows:
Before:
.. code-block:: c++
template <typename... TYPE_parameters> {
void FUNCTION(int... TYPE_parameters);
}
After:
.. code-block:: c++
template <typename... TYPE_parameters> {
void FUNCTION(int... pre_type_parameters_post);
}
.. option:: PointerParameterCase
When defined, the check will ensure pointer parameter names conform to the
selected casing.
.. option:: PointerParameterPrefix
When defined, the check will ensure pointer parameter names will add the
prefixed with the given value (regardless of casing).
.. option:: PointerParameterIgnoredRegexp
Identifier naming checks won't be enforced for pointer parameter names
matching this regular expression.
.. option:: PointerParameterSuffix
When defined, the check will ensure pointer parameter names will add the
suffix with the given value (regardless of casing).
For example using values of:
- PointerParameterCase of ``lower_case``
- PointerParameterPrefix of ``pre_``
- PointerParameterSuffix of ``_post``
Identifies and/or transforms pointer parameter names as follows:
Before:
.. code-block:: c++
void FUNCTION(int *PARAMETER);
After:
.. code-block:: c++
void FUNCTION(int *pre_parameter_post);
.. option:: PrivateMemberCase
When defined, the check will ensure private member names conform to the
selected casing.
.. option:: PrivateMemberPrefix
When defined, the check will ensure private member names will add the
prefixed with the given value (regardless of casing).
.. option:: PrivateMemberIgnoredRegexp
Identifier naming checks won't be enforced for private member names
matching this regular expression.
.. option:: PrivateMemberSuffix
When defined, the check will ensure private member names will add the
suffix with the given value (regardless of casing).
For example using values of:
- PrivateMemberCase of ``lower_case``
- PrivateMemberPrefix of ``pre_``
- PrivateMemberSuffix of ``_post``
Identifies and/or transforms private member names as follows:
Before:
.. code-block:: c++
class Foo {
private:
int Member_Variable;
}
After:
.. code-block:: c++
class Foo {
private:
int pre_member_variable_post;
}
.. option:: PrivateMethodCase
When defined, the check will ensure private method names conform to the
selected casing.
.. option:: PrivateMethodPrefix
When defined, the check will ensure private method names will add the
prefixed with the given value (regardless of casing).
.. option:: PrivateMethodIgnoredRegexp
Identifier naming checks won't be enforced for private method names
matching this regular expression.
.. option:: PrivateMethodSuffix
When defined, the check will ensure private method names will add the
suffix with the given value (regardless of casing).
For example using values of:
- PrivateMethodCase of ``lower_case``
- PrivateMethodPrefix of ``pre_``
- PrivateMethodSuffix of ``_post``
Identifies and/or transforms private method names as follows:
Before:
.. code-block:: c++
class Foo {
private:
int Member_Method();
}
After:
.. code-block:: c++
class Foo {
private:
int pre_member_method_post();
}
.. option:: ProtectedMemberCase
When defined, the check will ensure protected member names conform to the
selected casing.
.. option:: ProtectedMemberPrefix
When defined, the check will ensure protected member names will add the
prefixed with the given value (regardless of casing).
.. option:: ProtectedMemberIgnoredRegexp
Identifier naming checks won't be enforced for protected member names
matching this regular expression.
.. option:: ProtectedMemberSuffix
When defined, the check will ensure protected member names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ProtectedMemberCase of ``lower_case``
- ProtectedMemberPrefix of ``pre_``
- ProtectedMemberSuffix of ``_post``
Identifies and/or transforms protected member names as follows:
Before:
.. code-block:: c++
class Foo {
protected:
int Member_Variable;
}
After:
.. code-block:: c++
class Foo {
protected:
int pre_member_variable_post;
}
.. option:: ProtectedMethodCase
When defined, the check will ensure protected method names conform to the
selected casing.
.. option:: ProtectedMethodPrefix
When defined, the check will ensure protected method names will add the
prefixed with the given value (regardless of casing).
.. option:: ProtectedMethodIgnoredRegexp
Identifier naming checks won't be enforced for protected method names
matching this regular expression.
.. option:: ProtectedMethodSuffix
When defined, the check will ensure protected method names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ProtectedMethodCase of ``lower_case``
- ProtectedMethodPrefix of ``pre_``
- ProtectedMethodSuffix of ``_post``
Identifies and/or transforms protect method names as follows:
Before:
.. code-block:: c++
class Foo {
protected:
int Member_Method();
}
After:
.. code-block:: c++
class Foo {
protected:
int pre_member_method_post();
}
.. option:: PublicMemberCase
When defined, the check will ensure public member names conform to the
selected casing.
.. option:: PublicMemberPrefix
When defined, the check will ensure public member names will add the
prefixed with the given value (regardless of casing).
.. option:: PublicMemberIgnoredRegexp
Identifier naming checks won't be enforced for public member names
matching this regular expression.
.. option:: PublicMemberSuffix
When defined, the check will ensure public member names will add the
suffix with the given value (regardless of casing).
For example using values of:
- PublicMemberCase of ``lower_case``
- PublicMemberPrefix of ``pre_``
- PublicMemberSuffix of ``_post``
Identifies and/or transforms public member names as follows:
Before:
.. code-block:: c++
class Foo {
public:
int Member_Variable;
}
After:
.. code-block:: c++
class Foo {
public:
int pre_member_variable_post;
}
.. option:: PublicMethodCase
When defined, the check will ensure public method names conform to the
selected casing.
.. option:: PublicMethodPrefix
When defined, the check will ensure public method names will add the
prefixed with the given value (regardless of casing).
.. option:: PublicMethodIgnoredRegexp
Identifier naming checks won't be enforced for public method names
matching this regular expression.
.. option:: PublicMethodSuffix
When defined, the check will ensure public method names will add the
suffix with the given value (regardless of casing).
For example using values of:
- PublicMethodCase of ``lower_case``
- PublicMethodPrefix of ``pre_``
- PublicMethodSuffix of ``_post``
Identifies and/or transforms public method names as follows:
Before:
.. code-block:: c++
class Foo {
public:
int Member_Method();
}
After:
.. code-block:: c++
class Foo {
public:
int pre_member_method_post();
}
.. option:: ScopedEnumConstantCase
When defined, the check will ensure scoped enum constant names conform to
the selected casing.
.. option:: ScopedEnumConstantPrefix
When defined, the check will ensure scoped enum constant names will add the
prefixed with the given value (regardless of casing).
.. option:: ScopedEnumConstantIgnoredRegexp
Identifier naming checks won't be enforced for scoped enum constant names
matching this regular expression.
.. option:: ScopedEnumConstantSuffix
When defined, the check will ensure scoped enum constant names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ScopedEnumConstantCase of ``lower_case``
- ScopedEnumConstantPrefix of ``pre_``
- ScopedEnumConstantSuffix of ``_post``
Identifies and/or transforms enumeration constant names as follows:
Before:
.. code-block:: c++
enum class FOO { One, Two, Three };
After:
.. code-block:: c++
enum class FOO { pre_One_post, pre_Two_post, pre_Three_post };
.. option:: StaticConstantCase
When defined, the check will ensure static constant names conform to the
selected casing.
.. option:: StaticConstantPrefix
When defined, the check will ensure static constant names will add the
prefixed with the given value (regardless of casing).
.. option:: StaticConstantIgnoredRegexp
Identifier naming checks won't be enforced for static constant names
matching this regular expression.
.. option:: StaticConstantSuffix
When defined, the check will ensure static constant names will add the
suffix with the given value (regardless of casing).
For example using values of:
- StaticConstantCase of ``lower_case``
- StaticConstantPrefix of ``pre_``
- StaticConstantSuffix of ``_post``
Identifies and/or transforms static constant names as follows:
Before:
.. code-block:: c++
static unsigned const MyConstStatic_array[] = {1, 2, 3};
After:
.. code-block:: c++
static unsigned const pre_myconststatic_array_post[] = {1, 2, 3};
.. option:: StaticVariableCase
When defined, the check will ensure static variable names conform to the
selected casing.
.. option:: StaticVariablePrefix
When defined, the check will ensure static variable names will add the
prefixed with the given value (regardless of casing).
.. option:: StaticVariableIgnoredRegexp
Identifier naming checks won't be enforced for static variable names
matching this regular expression.
.. option:: StaticVariableSuffix
When defined, the check will ensure static variable names will add the
suffix with the given value (regardless of casing).
For example using values of:
- StaticVariableCase of ``lower_case``
- StaticVariablePrefix of ``pre_``
- StaticVariableSuffix of ``_post``
Identifies and/or transforms static variable names as follows:
Before:
.. code-block:: c++
static unsigned MyStatic_array[] = {1, 2, 3};
After:
.. code-block:: c++
static unsigned pre_mystatic_array_post[] = {1, 2, 3};
.. option:: StructCase
When defined, the check will ensure struct names conform to the
selected casing.
.. option:: StructPrefix
When defined, the check will ensure struct names will add the
prefixed with the given value (regardless of casing).
.. option:: StructIgnoredRegexp
Identifier naming checks won't be enforced for struct names
matching this regular expression.
.. option:: StructSuffix
When defined, the check will ensure struct names will add the
suffix with the given value (regardless of casing).
For example using values of:
- StructCase of ``lower_case``
- StructPrefix of ``pre_``
- StructSuffix of ``_post``
Identifies and/or transforms struct names as follows:
Before:
.. code-block:: c++
struct FOO {
FOO();
~FOO();
};
After:
.. code-block:: c++
struct pre_foo_post {
pre_foo_post();
~pre_foo_post();
};
.. option:: TemplateParameterCase
When defined, the check will ensure template parameter names conform to the
selected casing.
.. option:: TemplateParameterPrefix
When defined, the check will ensure template parameter names will add the
prefixed with the given value (regardless of casing).
.. option:: TemplateParameterIgnoredRegexp
Identifier naming checks won't be enforced for template parameter names
matching this regular expression.
.. option:: TemplateParameterSuffix
When defined, the check will ensure template parameter names will add the
suffix with the given value (regardless of casing).
For example using values of:
- TemplateParameterCase of ``lower_case``
- TemplateParameterPrefix of ``pre_``
- TemplateParameterSuffix of ``_post``
Identifies and/or transforms template parameter names as follows:
Before:
.. code-block:: c++
template <typename T> class Foo {};
After:
.. code-block:: c++
template <typename pre_t_post> class Foo {};
.. option:: TemplateTemplateParameterCase
When defined, the check will ensure template template parameter names conform to the
selected casing.
.. option:: TemplateTemplateParameterPrefix
When defined, the check will ensure template template parameter names will add the
prefixed with the given value (regardless of casing).
.. option:: TemplateTemplateParameterIgnoredRegexp
Identifier naming checks won't be enforced for template template parameter
names matching this regular expression.
.. option:: TemplateTemplateParameterSuffix
When defined, the check will ensure template template parameter names will add the
suffix with the given value (regardless of casing).
For example using values of:
- TemplateTemplateParameterCase of ``lower_case``
- TemplateTemplateParameterPrefix of ``pre_``
- TemplateTemplateParameterSuffix of ``_post``
Identifies and/or transforms template template parameter names as follows:
Before:
.. code-block:: c++
template <template <typename> class TPL_parameter, int COUNT_params,
typename... TYPE_parameters>
After:
.. code-block:: c++
template <template <typename> class pre_tpl_parameter_post, int COUNT_params,
typename... TYPE_parameters>
.. option:: TypeAliasCase
When defined, the check will ensure type alias names conform to the
selected casing.
.. option:: TypeAliasPrefix
When defined, the check will ensure type alias names will add the
prefixed with the given value (regardless of casing).
.. option:: TypeAliasIgnoredRegexp
Identifier naming checks won't be enforced for type alias names
matching this regular expression.
.. option:: TypeAliasSuffix
When defined, the check will ensure type alias names will add the
suffix with the given value (regardless of casing).
For example using values of:
- TypeAliasCase of ``lower_case``
- TypeAliasPrefix of ``pre_``
- TypeAliasSuffix of ``_post``
Identifies and/or transforms type alias names as follows:
Before:
.. code-block:: c++
using MY_STRUCT_TYPE = my_structure;
After:
.. code-block:: c++
using pre_my_struct_type_post = my_structure;
.. option:: TypedefCase
When defined, the check will ensure typedef names conform to the
selected casing.
.. option:: TypedefPrefix
When defined, the check will ensure typedef names will add the
prefixed with the given value (regardless of casing).
.. option:: TypedefIgnoredRegexp
Identifier naming checks won't be enforced for typedef names
matching this regular expression.
.. option:: TypedefSuffix
When defined, the check will ensure typedef names will add the
suffix with the given value (regardless of casing).
For example using values of:
- TypedefCase of ``lower_case``
- TypedefPrefix of ``pre_``
- TypedefSuffix of ``_post``
Identifies and/or transforms typedef names as follows:
Before:
.. code-block:: c++
typedef int MYINT;
After:
.. code-block:: c++
typedef int pre_myint_post;
.. option:: TypeTemplateParameterCase
When defined, the check will ensure type template parameter names conform to the
selected casing.
.. option:: TypeTemplateParameterPrefix
When defined, the check will ensure type template parameter names will add the
prefixed with the given value (regardless of casing).
.. option:: TypeTemplateParameterIgnoredRegexp
Identifier naming checks won't be enforced for type template names
matching this regular expression.
.. option:: TypeTemplateParameterSuffix
When defined, the check will ensure type template parameter names will add the
suffix with the given value (regardless of casing).
For example using values of:
- TypeTemplateParameterCase of ``lower_case``
- TypeTemplateParameterPrefix of ``pre_``
- TypeTemplateParameterSuffix of ``_post``
Identifies and/or transforms type template parameter names as follows:
Before:
.. code-block:: c++
template <template <typename> class TPL_parameter, int COUNT_params,
typename... TYPE_parameters>
After:
.. code-block:: c++
template <template <typename> class TPL_parameter, int COUNT_params,
typename... pre_type_parameters_post>
.. option:: UnionCase
When defined, the check will ensure union names conform to the
selected casing.
.. option:: UnionPrefix
When defined, the check will ensure union names will add the
prefixed with the given value (regardless of casing).
.. option:: UnionIgnoredRegexp
Identifier naming checks won't be enforced for union names
matching this regular expression.
.. option:: UnionSuffix
When defined, the check will ensure union names will add the
suffix with the given value (regardless of casing).
For example using values of:
- UnionCase of ``lower_case``
- UnionPrefix of ``pre_``
- UnionSuffix of ``_post``
Identifies and/or transforms union names as follows:
Before:
.. code-block:: c++
union FOO {
int a;
char b;
};
After:
.. code-block:: c++
union pre_foo_post {
int a;
char b;
};
.. option:: ValueTemplateParameterCase
When defined, the check will ensure value template parameter names conform to the
selected casing.
.. option:: ValueTemplateParameterPrefix
When defined, the check will ensure value template parameter names will add the
prefixed with the given value (regardless of casing).
.. option:: ValueTemplateParameterIgnoredRegexp
Identifier naming checks won't be enforced for value template parameter
names matching this regular expression.
.. option:: ValueTemplateParameterSuffix
When defined, the check will ensure value template parameter names will add the
suffix with the given value (regardless of casing).
For example using values of:
- ValueTemplateParameterCase of ``lower_case``
- ValueTemplateParameterPrefix of ``pre_``
- ValueTemplateParameterSuffix of ``_post``
Identifies and/or transforms value template parameter names as follows:
Before:
.. code-block:: c++
template <template <typename> class TPL_parameter, int COUNT_params,
typename... TYPE_parameters>
After:
.. code-block:: c++
template <template <typename> class TPL_parameter, int pre_count_params_post,
typename... TYPE_parameters>
.. option:: VariableCase
When defined, the check will ensure variable names conform to the
selected casing.
.. option:: VariablePrefix
When defined, the check will ensure variable names will add the
prefixed with the given value (regardless of casing).
.. option:: VariableIgnoredRegexp
Identifier naming checks won't be enforced for variable names
matching this regular expression.
.. option:: VariableSuffix
When defined, the check will ensure variable names will add the
suffix with the given value (regardless of casing).
For example using values of:
- VariableCase of ``lower_case``
- VariablePrefix of ``pre_``
- VariableSuffix of ``_post``
Identifies and/or transforms variable names as follows:
Before:
.. code-block:: c++
unsigned MyVariable;
After:
.. code-block:: c++
unsigned pre_myvariable_post;
.. option:: VirtualMethodCase
When defined, the check will ensure virtual method names conform to the
selected casing.
.. option:: VirtualMethodPrefix
When defined, the check will ensure virtual method names will add the
prefixed with the given value (regardless of casing).
.. option:: VirtualMethodIgnoredRegexp
Identifier naming checks won't be enforced for virtual method names
matching this regular expression.
.. option:: VirtualMethodSuffix
When defined, the check will ensure virtual method names will add the
suffix with the given value (regardless of casing).
For example using values of:
- VirtualMethodCase of ``lower_case``
- VirtualMethodPrefix of ``pre_``
- VirtualMethodSuffix of ``_post``
Identifies and/or transforms virtual method names as follows:
Before:
.. code-block:: c++
class Foo {
public:
virtual int MemberFunction();
}
After:
.. code-block:: c++
class Foo {
public:
virtual int pre_member_function_post();
}
.. title:: clang-tidy - readability-implicit-bool-conversion
readability-implicit-bool-conversion
====================================
This check can be used to find implicit conversions between built-in types and
booleans. Depending on use case, it may simply help with readability of the code,
or in some cases, point to potential bugs which remain unnoticed due to implicit
conversions.
The following is a real-world example of bug which was hiding behind implicit
``bool`` conversion:
.. code-block:: c++
class Foo {
int m_foo;
public:
void setFoo(bool foo) { m_foo = foo; } // warning: implicit conversion bool -> int
int getFoo() { return m_foo; }
};
void use(Foo& foo) {
bool value = foo.getFoo(); // warning: implicit conversion int -> bool
}
This code is the result of unsuccessful refactoring, where type of ``m_foo``
changed from ``bool`` to ``int``. The programmer forgot to change all
occurrences of ``bool``, and the remaining code is no longer correct, yet it
still compiles without any visible warnings.
In addition to issuing warnings, fix-it hints are provided to help solve the
reported issues. This can be used for improving readability of code, for
example:
.. code-block:: c++
void conversionsToBool() {
float floating;
bool boolean = floating;
// ^ propose replacement: bool boolean = floating != 0.0f;
int integer;
if (integer) {}
// ^ propose replacement: if (integer != 0) {}
int* pointer;
if (!pointer) {}
// ^ propose replacement: if (pointer == nullptr) {}
while (1) {}
// ^ propose replacement: while (true) {}
}
void functionTakingInt(int param);
void conversionsFromBool() {
bool boolean;
functionTakingInt(boolean);
// ^ propose replacement: functionTakingInt(static_cast<int>(boolean));
functionTakingInt(true);
// ^ propose replacement: functionTakingInt(1);
}
In general, the following conversion types are checked:
- integer expression/literal to boolean (conversion from a single bit bitfield
to boolean is explicitly allowed, since there's no ambiguity / information
loss in this case),
- floating expression/literal to boolean,
- pointer/pointer to member/``nullptr``/``NULL`` to boolean,
- boolean expression/literal to integer (conversion from boolean to a single
bit bitfield is explicitly allowed),
- boolean expression/literal to floating.
The rules for generating fix-it hints are:
- in case of conversions from other built-in type to bool, an explicit
comparison is proposed to make it clear what exactly is being compared:
- ``bool boolean = floating;`` is changed to
``bool boolean = floating == 0.0f;``,
- for other types, appropriate literals are used (``0``, ``0u``, ``0.0f``,
``0.0``, ``nullptr``),
- in case of negated expressions conversion to bool, the proposed replacement
with comparison is simplified:
- ``if (!pointer)`` is changed to ``if (pointer == nullptr)``,
- in case of conversions from bool to other built-in types, an explicit
``static_cast`` is proposed to make it clear that a conversion is taking
place:
- ``int integer = boolean;`` is changed to
``int integer = static_cast<int>(boolean);``,
- if the conversion is performed on type literals, an equivalent literal is
proposed, according to what type is actually expected, for example:
- ``functionTakingBool(0);`` is changed to ``functionTakingBool(false);``,
- ``functionTakingInt(true);`` is changed to ``functionTakingInt(1);``,
- for other types, appropriate literals are used (``false``, ``true``, ``0``,
``1``, ``0u``, ``1u``, ``0.0f``, ``1.0f``, ``0.0``, ``1.0f``).
Some additional accommodations are made for pre-C++11 dialects:
- ``false`` literal conversion to pointer is detected,
- instead of ``nullptr`` literal, ``0`` is proposed as replacement.
Occurrences of implicit conversions inside macros and template instantiations
are deliberately ignored, as it is not clear how to deal with such cases.
Options
-------
.. option:: AllowIntegerConditions
When `true`, the check will allow conditional integer conversions. Default
is `false`.
.. option:: AllowPointerConditions
When `true`, the check will allow conditional pointer conversions. Default
is `false`.
.. title:: clang-tidy - readability-inconsistent-declaration-parameter-name
readability-inconsistent-declaration-parameter-name
===================================================
Find function declarations which differ in parameter names.
Example:
.. code-block:: c++
// in foo.hpp:
void foo(int a, int b, int c);
// in foo.cpp:
void foo(int d, int e, int f); // warning
This check should help to enforce consistency in large projects, where it often
happens that a definition of function is refactored, changing the parameter
names, but its declaration in header file is not updated. With this check, we
can easily find and correct such inconsistencies, keeping declaration and
definition always in sync.
Unnamed parameters are allowed and are not taken into account when comparing
function declarations, for example:
.. code-block:: c++
void foo(int a);
void foo(int); // no warning
One name is also allowed to be a case-insensitive prefix/suffix of the other:
.. code-block:: c++
void foo(int count);
void foo(int count_input) { // no warning
int count = adjustCount(count_input);
}
To help with refactoring, in some cases fix-it hints are generated to align
parameter names to a single naming convention. This works with the assumption
that the function definition is the most up-to-date version, as it directly
references parameter names in its body. Example:
.. code-block:: c++
void foo(int a); // warning and fix-it hint (replace "a" to "b")
int foo(int b) { return b + 2; } // definition with use of "b"
In the case of multiple redeclarations or function template specializations,
a warning is issued for every redeclaration or specialization inconsistent with
the definition or the first declaration seen in a translation unit.
.. option:: IgnoreMacros
If this option is set to `true` (default is `true`), the check will not warn
about names declared inside macros.
.. option:: Strict
If this option is set to `true` (default is `false`), then names must match
exactly (or be absent).
.. title:: clang-tidy - readability-isolate-declaration
readability-isolate-declaration
===============================
Detects local variable declarations declaring more than one variable and
tries to refactor the code to one statement per declaration.
The automatic code-transformation will use the same indentation as the original
for every created statement and add a line break after each statement.
It keeps the order of the variable declarations consistent, too.
.. code-block:: c++
void f() {
int * pointer = nullptr, value = 42, * const const_ptr = &value;
// This declaration will be diagnosed and transformed into:
// int * pointer = nullptr;
// int value = 42;
// int * const const_ptr = &value;
}
The check excludes places where it is necessary or common to declare
multiple variables in one statement and there is no other way supported in the
language. Please note that structured bindings are not considered.
.. code-block:: c++
// It is not possible to transform this declaration and doing the declaration
// before the loop will increase the scope of the variable 'Begin' and 'End'
// which is undesirable.
for (int Begin = 0, End = 100; Begin < End; ++Begin);
if (int Begin = 42, Result = some_function(Begin); Begin == Result);
// It is not possible to transform this declaration because the result is
// not functionality preserving as 'j' and 'k' would not be part of the
// 'if' statement anymore.
if (SomeCondition())
int i = 42, j = 43, k = function(i,j);
Limitations
-----------
Global variables and member variables are excluded.
The check currently does not support the automatic transformation of
member-pointer-types.
.. code-block:: c++
struct S {
int a;
const int b;
void f() {}
};
void f() {
// Only a diagnostic message is emitted
int S::*p = &S::a, S::*const q = &S::a;
}
Furthermore, the transformation is very cautious when it detects various kinds
of macros or preprocessor directives in the range of the statement. In this
case the transformation will not happen to avoid unexpected side-effects due to
macros.
.. code-block:: c++
#define NULL 0
#define MY_NICE_TYPE int **
#define VAR_NAME(name) name##__LINE__
#define A_BUNCH_OF_VARIABLES int m1 = 42, m2 = 43, m3 = 44;
void macros() {
int *p1 = NULL, *p2 = NULL;
// Will be transformed to
// int *p1 = NULL;
// int *p2 = NULL;
MY_NICE_TYPE p3, v1, v2;
// Won't be transformed, but a diagnostic is emitted.
int VAR_NAME(v3),
VAR_NAME(v4),
VAR_NAME(v5);
// Won't be transformed, but a diagnostic is emitted.
A_BUNCH_OF_VARIABLES
// Won't be transformed, but a diagnostic is emitted.
int Unconditional,
#if CONFIGURATION
IfConfigured = 42,
#else
IfConfigured = 0;
#endif
// Won't be transformed, but a diagnostic is emitted.
}
.. title:: clang-tidy - readability-make-member-function-const
readability-make-member-function-const
======================================
Finds non-static member functions that can be made ``const``
because the functions don't use ``this`` in a non-const way.
This check tries to annotate methods according to
`logical constness <https://isocpp.org/wiki/faq/const-correctness#logical-vs-physical-state>`_
(not physical constness).
Therefore, it will suggest to add a ``const`` qualifier to a non-const
method only if this method does something that is already possible though the
public interface on a ``const`` pointer to the object:
* reading a public member variable
* calling a public const-qualified member function
* returning const-qualified ``this``
* passing const-qualified ``this`` as a parameter.
This check will also suggest to add a ``const`` qualifier to a non-const
method if this method uses private data and functions in a limited number of
ways where logical constness and physical constness coincide:
* reading a member variable of builtin type
Specifically, this check will not suggest to add a ``const`` to a non-const
method if the method reads a private member variable of pointer type because
that allows to modify the pointee which might not preserve logical constness.
For the same reason, it does not allow to call private member functions
or member functions on private member variables.
In addition, this check ignores functions that
* are declared ``virtual``
* contain a ``const_cast``
* are templated or part of a class template
* have an empty body
* do not (implicitly) use ``this`` at all
(see `readability-convert-member-functions-to-static <readability-convert-member-functions-to-static.html>`_).
The following real-world examples will be preserved by the check:
.. code-block:: c++
class E1 {
Pimpl &getPimpl() const;
public:
int &get() {
// Calling a private member function disables this check.
return getPimpl()->i;
}
...
};
class E2 {
public:
const int *get() const;
// const_cast disables this check.
S *get() {
return const_cast<int*>(const_cast<const C*>(this)->get());
}
...
};
After applying modifications as suggested by the check, running the check again
might find more opportunities to mark member functions ``const``.
.. title:: clang-tidy - readability-misplaced-array-index
readability-misplaced-array-index
=================================
This check warns for unusual array index syntax.
The following code has unusual array index syntax:
.. code-block:: c++
void f(int *X, int Y) {
Y[X] = 0;
}
becomes
.. code-block:: c++
void f(int *X, int Y) {
X[Y] = 0;
}
The check warns about such unusual syntax for readability reasons:
* There are programmers that are not familiar with this unusual syntax.
* It is possible that variables are mixed up.
.. title:: clang-tidy - readability-named-parameter
readability-named-parameter
===========================
Find functions with unnamed arguments.
The check implements the following rule originating in the Google C++ Style
Guide:
https://google.github.io/styleguide/cppguide.html#Function_Declarations_and_Definitions
All parameters should be named, with identical names in the declaration and
implementation.
Corresponding cpplint.py check name: `readability/function`.
.. title:: clang-tidy - readability-non-const-parameter
readability-non-const-parameter
===============================
The check finds function parameters of a pointer type that could be changed to
point to a constant type instead.
When ``const`` is used properly, many mistakes can be avoided. Advantages when
using ``const`` properly:
- prevent unintentional modification of data;
- get additional warnings such as using uninitialized data;
- make it easier for developers to see possible side effects.
This check is not strict about constness, it only warns when the constness will
make the function interface safer.
.. code-block:: c++
// warning here; the declaration "const char *p" would make the function
// interface safer.
char f1(char *p) {
return *p;
}
// no warning; the declaration could be more const "const int * const p" but
// that does not make the function interface safer.
int f2(const int *p) {
return *p;
}
// no warning; making x const does not make the function interface safer
int f3(int x) {
return x;
}
// no warning; Technically, *p can be const ("const struct S *p"). But making
// *p const could be misleading. People might think that it's safe to pass
// const data to this function.
struct S { int *a; int *b; };
int f3(struct S *p) {
*(p->a) = 0;
}
.. title:: clang-tidy - readability-qualified-auto
readability-qualified-auto
==========================
Adds pointer qualifications to ``auto``-typed variables that are deduced to
pointers.
`LLVM Coding Standards <https://llvm.org/docs/CodingStandards.html#beware-unnecessary-copies-with-auto>`_
advises to make it obvious if a ``auto`` typed variable is a pointer. This
check will transform ``auto`` to ``auto *`` when the type is deduced to be a
pointer.
.. code-block:: c++
for (auto Data : MutatablePtrContainer) {
change(*Data);
}
for (auto Data : ConstantPtrContainer) {
observe(*Data);
}
Would be transformed into:
.. code-block:: c++
for (auto *Data : MutatablePtrContainer) {
change(*Data);
}
for (const auto *Data : ConstantPtrContainer) {
observe(*Data);
}
Note ``const`` ``volatile`` qualified types will retain their ``const`` and
``volatile`` qualifiers. Pointers to pointers will not be fully qualified.
.. code-block:: c++
const auto Foo = cast<int *>(Baz1);
const auto Bar = cast<const int *>(Baz2);
volatile auto FooBar = cast<int *>(Baz3);
auto BarFoo = cast<int **>(Baz4);
Would be transformed into:
.. code-block:: c++
auto *const Foo = cast<int *>(Baz1);
const auto *const Bar = cast<const int *>(Baz2);
auto *volatile FooBar = cast<int *>(Baz3);
auto *BarFoo = cast<int **>(Baz4);
Options
-------
.. option:: AddConstToQualified
When set to `true` the check will add const qualifiers variables defined as
``auto *`` or ``auto &`` when applicable.
Default value is `true`.
.. code-block:: c++
auto Foo1 = cast<const int *>(Bar1);
auto *Foo2 = cast<const int *>(Bar2);
auto &Foo3 = cast<const int &>(Bar3);
If AddConstToQualified is set to `false`, it will be transformed into:
.. code-block:: c++
const auto *Foo1 = cast<const int *>(Bar1);
auto *Foo2 = cast<const int *>(Bar2);
auto &Foo3 = cast<const int &>(Bar3);
Otherwise it will be transformed into:
.. code-block:: c++
const auto *Foo1 = cast<const int *>(Bar1);
const auto *Foo2 = cast<const int *>(Bar2);
const auto &Foo3 = cast<const int &>(Bar3);
Note in the LLVM alias, the default value is `false`.
.. title:: clang-tidy - readability-redundant-access-specifiers
readability-redundant-access-specifiers
=======================================
Finds classes, structs, and unions containing redundant member (field and
method) access specifiers.
Example
-------
.. code-block:: c++
class Foo {
public:
int x;
int y;
public:
int z;
protected:
int a;
public:
int c;
}
In the example above, the second ``public`` declaration can be removed without
any changes of behavior.
Options
-------
.. option:: CheckFirstDeclaration
If set to `true`, the check will also diagnose if the first access
specifier declaration is redundant (e.g. ``private`` inside ``class``,
or ``public`` inside ``struct`` or ``union``).
Default is `false`.
Example
^^^^^^^
.. code-block:: c++
struct Bar {
public:
int x;
}
If `CheckFirstDeclaration` option is enabled, a warning about redundant
access specifier will be emitted, because ``public`` is the default member access
for structs.
.. title:: clang-tidy - readability-redundant-control-flow
readability-redundant-control-flow
==================================
This check looks for procedures (functions returning no value) with ``return``
statements at the end of the function. Such ``return`` statements are redundant.
Loop statements (``for``, ``while``, ``do while``) are checked for redundant
``continue`` statements at the end of the loop body.
Examples:
The following function `f` contains a redundant ``return`` statement:
.. code-block:: c++
extern void g();
void f() {
g();
return;
}
becomes
.. code-block:: c++
extern void g();
void f() {
g();
}
The following function `k` contains a redundant ``continue`` statement:
.. code-block:: c++
void k() {
for (int i = 0; i < 10; ++i) {
continue;
}
}
becomes
.. code-block:: c++
void k() {
for (int i = 0; i < 10; ++i) {
}
}
.. title:: clang-tidy - readability-redundant-declaration
readability-redundant-declaration
=================================
Finds redundant variable and function declarations.
.. code-block:: c++
extern int X;
extern int X;
becomes
.. code-block:: c++
extern int X;
Such redundant declarations can be removed without changing program behaviour.
They can for instance be unintentional left overs from previous refactorings
when code has been moved around. Having redundant declarations could in worst
case mean that there are typos in the code that cause bugs.
Normally the code can be automatically fixed, :program:`clang-tidy` can remove
the second declaration. However there are 2 cases when you need to fix the code
manually:
* When the declarations are in different header files;
* When multiple variables are declared together.
Options
-------
.. option:: IgnoreMacros
If set to `true`, the check will not give warnings inside macros. Default
is `true`.
.. title:: clang-tidy - readability-redundant-function-ptr-dereference
readability-redundant-function-ptr-dereference
==============================================
Finds redundant dereferences of a function pointer.
Before:
.. code-block:: c++
int f(int,int);
int (*p)(int, int) = &f;
int i = (**p)(10, 50);
After:
.. code-block:: c++
int f(int,int);
int (*p)(int, int) = &f;
int i = (*p)(10, 50);
.. title:: clang-tidy - readability-redundant-member-init
readability-redundant-member-init
=================================
Finds member initializations that are unnecessary because the same default
constructor would be called if they were not present.
Example
-------
.. code-block:: c++
// Explicitly initializing the member s is unnecessary.
class Foo {
public:
Foo() : s() {}
private:
std::string s;
};
Options
-------
.. option:: IgnoreBaseInCopyConstructors
Default is `false`.
When `true`, the check will ignore unnecessary base class initializations
within copy constructors, since some compilers issue warnings/errors when
base classes are not explicitly intialized in copy constructors. For example,
``gcc`` with ``-Wextra`` or ``-Werror=extra`` issues warning or error
``base class 'Bar' should be explicitly initialized in the copy constructor``
if ``Bar()`` were removed in the following example:
.. code-block:: c++
// Explicitly initializing member s and base class Bar is unnecessary.
struct Foo : public Bar {
// Remove s() below. If IgnoreBaseInCopyConstructors!=0, keep Bar().
Foo(const Foo& foo) : Bar(), s() {}
std::string s;
};
.. title:: clang-tidy - readability-redundant-smartptr-get
readability-redundant-smartptr-get
==================================
Find and remove redundant calls to smart pointer's ``.get()`` method.
Examples:
.. code-block:: c++
ptr.get()->Foo() ==> ptr->Foo()
*ptr.get() ==> *ptr
*ptr->get() ==> **ptr
if (ptr.get() == nullptr) ... => if (ptr == nullptr) ...
.. option:: IgnoreMacros
If this option is set to `true` (default is `true`), the check will not warn
about calls inside macros.
.. title:: clang-tidy - readability-redundant-string-cstr
readability-redundant-string-cstr
=================================
Finds unnecessary calls to ``std::string::c_str()`` and ``std::string::data()``.
.. title:: clang-tidy - readability-redundant-string-init
readability-redundant-string-init
=================================
Finds unnecessary string initializations.
Examples
--------
.. code-block:: c++
// Initializing string with empty string literal is unnecessary.
std::string a = "";
std::string b("");
// becomes
std::string a;
std::string b;
// Initializing a string_view with an empty string literal produces an
// instance that compares equal to string_view().
std::string_view a = "";
std::string_view b("");
// becomes
std::string_view a;
std::string_view b;
Options
-------
.. option:: StringNames
Default is `::std::basic_string;::std::basic_string_view`.
Semicolon-delimited list of class names to apply this check to.
By default `::std::basic_string` applies to ``std::string`` and
``std::wstring``. Set to e.g. `::std::basic_string;llvm::StringRef;QString`
to perform this check on custom classes.
.. title:: clang-tidy - readability-simplify-boolean-expr
readability-simplify-boolean-expr
=================================
Looks for boolean expressions involving boolean constants and simplifies
them to use the appropriate boolean expression directly.
Examples:
=========================================== ================
Initial expression Result
------------------------------------------- ----------------
``if (b == true)`` ``if (b)``
``if (b == false)`` ``if (!b)``
``if (b && true)`` ``if (b)``
``if (b && false)`` ``if (false)``
``if (b || true)`` ``if (true)``
``if (b || false)`` ``if (b)``
``e ? true : false`` ``e``
``e ? false : true`` ``!e``
``if (true) t(); else f();`` ``t();``
``if (false) t(); else f();`` ``f();``
``if (e) return true; else return false;`` ``return e;``
``if (e) return false; else return true;`` ``return !e;``
``if (e) b = true; else b = false;`` ``b = e;``
``if (e) b = false; else b = true;`` ``b = !e;``
``if (e) return true; return false;`` ``return e;``
``if (e) return false; return true;`` ``return !e;``
=========================================== ================
The resulting expression ``e`` is modified as follows:
1. Unnecessary parentheses around the expression are removed.
2. Negated applications of ``!`` are eliminated.
3. Negated applications of comparison operators are changed to use the
opposite condition.
4. Implicit conversions of pointers, including pointers to members, to
``bool`` are replaced with explicit comparisons to ``nullptr`` in C++11
or ``NULL`` in C++98/03.
5. Implicit casts to ``bool`` are replaced with explicit casts to ``bool``.
6. Object expressions with ``explicit operator bool`` conversion operators
are replaced with explicit casts to ``bool``.
7. Implicit conversions of integral types to ``bool`` are replaced with
explicit comparisons to ``0``.
Examples:
1. The ternary assignment ``bool b = (i < 0) ? true : false;`` has redundant
parentheses and becomes ``bool b = i < 0;``.
2. The conditional return ``if (!b) return false; return true;`` has an
implied double negation and becomes ``return b;``.
3. The conditional return ``if (i < 0) return false; return true;`` becomes
``return i >= 0;``.
The conditional return ``if (i != 0) return false; return true;`` becomes
``return i == 0;``.
4. The conditional return ``if (p) return true; return false;`` has an
implicit conversion of a pointer to ``bool`` and becomes
``return p != nullptr;``.
The ternary assignment ``bool b = (i & 1) ? true : false;`` has an
implicit conversion of ``i & 1`` to ``bool`` and becomes
``bool b = (i & 1) != 0;``.
5. The conditional return ``if (i & 1) return true; else return false;`` has
an implicit conversion of an integer quantity ``i & 1`` to ``bool`` and
becomes ``return (i & 1) != 0;``
6. Given ``struct X { explicit operator bool(); };``, and an instance ``x`` of
``struct X``, the conditional return ``if (x) return true; return false;``
becomes ``return static_cast<bool>(x);``
Options
-------
.. option:: ChainedConditionalReturn
If `true`, conditional boolean return statements at the end of an
``if/else if`` chain will be transformed. Default is `false`.
.. option:: ChainedConditionalAssignment
If `true`, conditional boolean assignments at the end of an ``if/else
if`` chain will be transformed. Default is `false`.
.. title:: clang-tidy - readability-simplify-subscript-expr
readability-simplify-subscript-expr
===================================
This check simplifies subscript expressions. Currently this covers calling
``.data()`` and immediately doing an array subscript operation to obtain a
single element, in which case simply calling ``operator[]`` suffice.
Examples:
.. code-block:: c++
std::string s = ...;
char c = s.data()[i]; // char c = s[i];
Options
-------
.. option:: Types
The list of type(s) that triggers this check. Default is
`::std::basic_string;::std::basic_string_view;::std::vector;::std::array`
.. title:: clang-tidy - readability-static-accessed-through-instance
readability-static-accessed-through-instance
============================================
Checks for member expressions that access static members through instances, and
replaces them with uses of the appropriate qualified-id.
Example:
The following code:
.. code-block:: c++
struct C {
static void foo();
static int x;
};
C *c1 = new C();
c1->foo();
c1->x;
is changed to:
.. code-block:: c++
C *c1 = new C();
C::foo();
C::x;
.. title:: clang-tidy - readability-static-definition-in-anonymous-namespace
readability-static-definition-in-anonymous-namespace
====================================================
Finds static function and variable definitions in anonymous namespace.
In this case, ``static`` is redundant, because anonymous namespace limits the
visibility of definitions to a single translation unit.
.. code-block:: c++
namespace {
static int a = 1; // Warning.
static const b = 1; // Warning.
}
The check will apply a fix by removing the redundant ``static`` qualifier.
.. title:: clang-tidy - readability-string-compare
readability-string-compare
==========================
Finds string comparisons using the compare method.
A common mistake is to use the string's ``compare`` method instead of using the
equality or inequality operators. The compare method is intended for sorting
functions and thus returns a negative number, a positive number or
zero depending on the lexicographical relationship between the strings compared.
If an equality or inequality check can suffice, that is recommended. This is
recommended to avoid the risk of incorrect interpretation of the return value
and to simplify the code. The string equality and inequality operators can
also be faster than the ``compare`` method due to early termination.
Examples:
.. code-block:: c++
std::string str1{"a"};
std::string str2{"b"};
// use str1 != str2 instead.
if (str1.compare(str2)) {
}
// use str1 == str2 instead.
if (!str1.compare(str2)) {
}
// use str1 == str2 instead.
if (str1.compare(str2) == 0) {
}
// use str1 != str2 instead.
if (str1.compare(str2) != 0) {
}
// use str1 == str2 instead.
if (0 == str1.compare(str2)) {
}
// use str1 != str2 instead.
if (0 != str1.compare(str2)) {
}
// Use str1 == "foo" instead.
if (str1.compare("foo") == 0) {
}
The above code examples shows the list of if-statements that this check will
give a warning for. All of them uses ``compare`` to check if equality or
inequality of two strings instead of using the correct operators.
.. title:: clang-tidy - readability-uniqueptr-delete-release
readability-uniqueptr-delete-release
====================================
Replace ``delete <unique_ptr>.release()`` with ``<unique_ptr> = nullptr``.
The latter is shorter, simpler and does not require use of raw pointer APIs.
.. code-block:: c++
std::unique_ptr<int> P;
delete P.release();
// becomes
std::unique_ptr<int> P;
P = nullptr;
Options
-------
.. option:: PreferResetCall
If `true`, refactor by calling the reset member function instead of
assigning to ``nullptr``. Default value is `false`.
.. code-block:: c++
std::unique_ptr<int> P;
delete P.release();
// becomes
std::unique_ptr<int> P;
P.reset();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment