Fall-through in switch cases is often considered risky.
Hence consider adding an unconditional break
for each switch clause.
Pointer offset(or any other arithmetic operation) on a pointer casted to a different type (than its original type) is risky and can result in undefined behaviour. The reason for such behaviour is that the memory alignment may change for types on every targeted platform.
Copying an object is an expensive operation, especially if the type of the object is not trivial to copy. To avoid creating an unnecessary copy of such object, use const references.
The analyser has found a local variable that can't be automatically moved. The reason for this behavior is the constness of the variable. Consider declaring the variable without the qualifier const
.
std::vector
in loop CXX-P2007Manually appending a significant number of elements to a std::vector
without reserving the memory upfront can cause performance issues as the memory needs to be reallocated and copied every time the std::vector
's size increases. This can be costly if many items need to be pushed into the std::vector
. Consider using the std::vector::reserve()
function to preallocate memory for the std::vector
before a loop containing a std::vector::push_back
.
While writing data to a buffer, the program can overrun the buffer's boundary and overwrite adjacent memory locations. These can either cause a crash if the memory region is inaccessible to the process for writing, or in the worst case produce a vulnerability to overwrite parts of the memory with untrusted user code.
posix_*
or pthread_*
return value tested to be negative CXX-W2013The pthread_*
or posix_*
functions (except posix_openpt
) always return a positive values.
When the functions mentioned above are used in negative integer range checks, the expression will always be resolved to false
as these functions return either zero (on success) or a positive err-no on failure.
Identifiers with typographically ambiguous names can be hard to read and adds unnecessary responsibility on the developer to be careful with the exact identifiers they are using.
Having identifiers unintentionally shadowed from the outer scope by the inner scope can possibly lead to bugs in code.
Consider using unique identifier names.
Default case provides switch statements with fallback, and in general is a good to have. Hence consider adding default case to switch.
*
, "
, '
, \
and /*
found in header names CXX-W1207Using special-meaning characters in header names can produce errors in parsing.
Consider cleaning up header names.
for
loop modified in body CXX-W1241Modifying the control variable of a for
loop in its body can make the code harder to read.
Consider using a while loop, or move the modification into the for
loop's update expression.
std::accumulate
CXX-W2005std::accumulate
folds the elements to the initial value type (provided as the last argument to std::accumulate
). When the initial value type is narrower than that of the elements to sum, there is a loss in precision.
float
to double
in a math function CXX-P2001Calling math functions from the C libray that only accept double
with float
arguments causes an implicit type promotion of the float
argument. Type promoting float
to double
costs extra space in memory, it also costs extra instructions for the conversion from float
and lastly vectorisation of float
is a lot more efficient compared to double
.
An inheriting class with a user-defined copy constructor must call its base class's copy constructor.
std::string_view
CXX-W2004The std::string_view
handle outlives it's data source instance.
std::string
CXX-P2003Found using sub-string based method find
for a character look-up.
A parameter is declared to be call-by-value when a const reference will suffice. This parameter type is expensive to copy.
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.
A pointer to the boolean type is used in the if
condition with implicit conversion. The same pointer is never dereferenced.
Call to "erase-remove" combination without end iterator results in incomplete removal of container elements when more than one element is removed.