Difference between revisions of "List of Code Linters"
m (→C++) |
|||
(13 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
+ | <seo title="List of Code Linters | Code Linters | RidgeRun" titlemode="replace" keywords="Linters, g++, clang++, cppcheck, cpplint, clang-tidy, clang-analyzer, 64 Bit Compatibility, Memory Leaks, clang-analyze, g++ -Weverything, clang++ -Weverything, Linter, ptr2int, ptr2long, int2ptr, long2ptr, ptr2int return, ptr2long return, int2ptr return, long2ptr return, preinc, postinc, Malloc, Calloc, Realloc" description="This RidgeRun developers wiki page is about the List of Code Linters."></seo> | ||
+ | |||
+ | |||
== C++ == | == C++ == | ||
Line 14: | Line 17: | ||
:A clang-based C++ linter | :A clang-based C++ linter | ||
;[https://clang-analyzer.llvm.org clang-analyzer] | ;[https://clang-analyzer.llvm.org clang-analyzer] | ||
− | :Another clang-based static | + | :Another clang-based static C++ linter with awesome reporting features. |
=== Checks === | === Checks === | ||
+ | |||
+ | ==== 64 Bit Compatibility ==== | ||
+ | |||
+ | <syntaxhighlight lang=c++> | ||
+ | // return cast from ptr to int | ||
+ | int ptr_to_int() | ||
+ | { | ||
+ | void * p = 0; | ||
+ | return p; | ||
+ | } | ||
+ | |||
+ | // return cast from ptr to long | ||
+ | long ptr_to_long() | ||
+ | { | ||
+ | void * p = 0; | ||
+ | return p; | ||
+ | } | ||
+ | |||
+ | // return cast from int to ptr | ||
+ | void * int_to_ptr() | ||
+ | { | ||
+ | int i = 0; | ||
+ | return i; | ||
+ | } | ||
+ | |||
+ | // return cast from long to ptr | ||
+ | void * long_to_ptr() | ||
+ | { | ||
+ | long l = 0; | ||
+ | return l; | ||
+ | } | ||
+ | |||
+ | int main () | ||
+ | { | ||
+ | void * p = 0; | ||
+ | |||
+ | // assign address to int | ||
+ | int i = p; | ||
+ | |||
+ | // assign address to long | ||
+ | long l = p; | ||
+ | |||
+ | //assign int to address | ||
+ | p = i; | ||
+ | |||
+ | //assign long to address | ||
+ | p = l; | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! Linter !! ptr2int !! ptr2long !! int2ptr !! long2ptr !! ptr2int return !! ptr2long return !! int2ptr return !! long2ptr return | ||
+ | |- | ||
+ | | g++ -Weverything || Y<ref name=no-compile>Wont even compile, still considered as a catch though</ref> || Y<ref name=no-compile/> || N || N || Y<ref name=no-compile/> || Y<ref name=no-compile/> || Y<ref name=no-compile/> || Y<ref name=no-compile/> | ||
+ | |- | ||
+ | | clang++ -Weverything || Y<ref name=no-compile>Wont even compile, still considered as a catch though</ref> || Y<ref name=no-compile/> || N || N || Y<ref name=no-compile/> || Y<ref name=no-compile/> || Y<ref name=no-compile/> || Y<ref name=no-compile/> | ||
+ | |- | ||
+ | | cppcheck<ref name=enable-all>Ran with --enable=all</ref> || Y<ref name=no-compile>Wont even compile, still considered as a catch though</ref> || Y<ref name=no-compile/> || N || N || Y<ref name=no-compile/> || Y<ref name=no-compile/> || Y<ref name=no-compile/> || Y<ref name=no-compile/> | ||
+ | |- | ||
+ | | cpplint || N || N || N || N || N || N || N || N | ||
+ | |- | ||
+ | | clang-tidy || Y<ref name=no-compile>Wont even compile, still considered as a catch though</ref> || Y<ref name=no-compile/> || N || N || Y<ref name=no-compile/> || Y<ref name=no-compile/> || Y<ref name=no-compile/> || Y<ref name=no-compile/> | ||
+ | |- | ||
+ | | clang-analyze || Y<ref name=no-compile>Wont even compile, still considered as a catch though</ref> || Y<ref name=no-compile/> || N || N || Y<ref name=no-compile/> || Y<ref name=no-compile/> || Y<ref name=no-compile/> || Y<ref name=no-compile/> | ||
+ | |} | ||
+ | <references/> | ||
+ | |||
+ | ==== Assert ==== | ||
+ | |||
+ | <syntaxhighlight lang=c++> | ||
+ | #include <assert.h> | ||
+ | |||
+ | volatile static int i = 0; | ||
+ | |||
+ | bool side_effect () | ||
+ | { | ||
+ | i++; | ||
+ | return true; | ||
+ | } | ||
+ | |||
+ | int main () | ||
+ | { | ||
+ | // Indirect assignment via preincrement | ||
+ | assert (++i); | ||
+ | |||
+ | // Indirect assignment via postincrement | ||
+ | assert (i++); | ||
+ | |||
+ | // Direct assignment in assert | ||
+ | assert (i = 1); | ||
+ | |||
+ | // Assert calling function with side effects | ||
+ | assert (side_effect()); | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! Linter !! preinc !! postinc !! assignment !! function | ||
+ | |- | ||
+ | | g++ -Weverything || N || N || N || N | ||
+ | |- | ||
+ | | clang++ -Weverything || N || N || N || N | ||
+ | |- | ||
+ | | cppcheck<ref name=enable-all>Ran with --enable=all</ref> || N<ref name=pr-preinc-assert>I sent a fix in https://github.com/danmar/cppcheck/pull/2605</ref> || Y || Y || Y | ||
+ | |- | ||
+ | | cpplint || N || N || N || N | ||
+ | |- | ||
+ | | clang-tidy || N || N || N || N | ||
+ | |- | ||
+ | | clang-analyze || N || N || N || N | ||
+ | |} | ||
+ | <references/> | ||
+ | |||
==== Memory Leaks (function variables) ==== | ==== Memory Leaks (function variables) ==== | ||
+ | <syntaxhighlight lang=c++> | ||
+ | #include <glib.h> | ||
+ | #include <stdlib.h> | ||
+ | int main () | ||
+ | { | ||
+ | // New | ||
+ | int *a = new int; | ||
+ | |||
+ | // Malloc | ||
+ | int *b = (int *)malloc(sizeof (int)); | ||
+ | |||
+ | // Calloc | ||
+ | int *c = (int *)calloc(1, sizeof (int)); | ||
+ | |||
+ | // Realloc | ||
+ | int *d = (int *)realloc(0, sizeof (int)); | ||
+ | |||
+ | // External library | ||
+ | int *e = (int *)g_malloc(sizeof (int)); | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 30: | Line 175: | ||
|- | |- | ||
| cppcheck || Y || Y || Y || Y | | cppcheck || Y || Y || Y || Y | ||
+ | |- | ||
+ | | cpplint || N || N || N || N | ||
|- | |- | ||
| clang-tidy || Y || Y || Y || Y | | clang-tidy || Y || Y || Y || Y | ||
Line 35: | Line 182: | ||
| clang-analyze || Y || Y || Y || Y | | clang-analyze || Y || Y || Y || Y | ||
|} | |} | ||
+ | <br> | ||
+ | {{ContactUs}} | ||
+ | |||
+ | [[Category:HowTo]] |
Latest revision as of 14:09, 20 December 2021
Contents
C++
Tools Considered
- g++
- The plain compiler invoked as
g++ -Weverything -c
on the file. Not ideal nor a real linter, but mainly for convenience. - clang++
- The plain compiler invoked as
clang++ -Weverything -c
on the file. Not ideal nor a real linter, but mainly for convenience. - cppcheck
- A C/C++ linter with a novel flow sensitive analysis.
- cpplint
- A linter built by google specifically for their coding standard.
- clang-tidy
- A clang-based C++ linter
- clang-analyzer
- Another clang-based static C++ linter with awesome reporting features.
Checks
64 Bit Compatibility
// return cast from ptr to int
int ptr_to_int()
{
void * p = 0;
return p;
}
// return cast from ptr to long
long ptr_to_long()
{
void * p = 0;
return p;
}
// return cast from int to ptr
void * int_to_ptr()
{
int i = 0;
return i;
}
// return cast from long to ptr
void * long_to_ptr()
{
long l = 0;
return l;
}
int main ()
{
void * p = 0;
// assign address to int
int i = p;
// assign address to long
long l = p;
//assign int to address
p = i;
//assign long to address
p = l;
return 0;
}
Linter | ptr2int | ptr2long | int2ptr | long2ptr | ptr2int return | ptr2long return | int2ptr return | long2ptr return |
---|---|---|---|---|---|---|---|---|
g++ -Weverything | Y[1] | Y[1] | N | N | Y[1] | Y[1] | Y[1] | Y[1] |
clang++ -Weverything | Y[1] | Y[1] | N | N | Y[1] | Y[1] | Y[1] | Y[1] |
cppcheck[2] | Y[1] | Y[1] | N | N | Y[1] | Y[1] | Y[1] | Y[1] |
cpplint | N | N | N | N | N | N | N | N |
clang-tidy | Y[1] | Y[1] | N | N | Y[1] | Y[1] | Y[1] | Y[1] |
clang-analyze | Y[1] | Y[1] | N | N | Y[1] | Y[1] | Y[1] | Y[1] |
Assert
#include <assert.h>
volatile static int i = 0;
bool side_effect ()
{
i++;
return true;
}
int main ()
{
// Indirect assignment via preincrement
assert (++i);
// Indirect assignment via postincrement
assert (i++);
// Direct assignment in assert
assert (i = 1);
// Assert calling function with side effects
assert (side_effect());
return 0;
}
Linter | preinc | postinc | assignment | function |
---|---|---|---|---|
g++ -Weverything | N | N | N | N |
clang++ -Weverything | N | N | N | N |
cppcheck[1] | N[2] | Y | Y | Y |
cpplint | N | N | N | N |
clang-tidy | N | N | N | N |
clang-analyze | N | N | N | N |
- ↑ Ran with --enable=all
- ↑ I sent a fix in https://github.com/danmar/cppcheck/pull/2605
Memory Leaks (function variables)
#include <glib.h>
#include <stdlib.h>
int main ()
{
// New
int *a = new int;
// Malloc
int *b = (int *)malloc(sizeof (int));
// Calloc
int *c = (int *)calloc(1, sizeof (int));
// Realloc
int *d = (int *)realloc(0, sizeof (int));
// External library
int *e = (int *)g_malloc(sizeof (int));
return 0;
}
Linter | New | Malloc | Calloc | Realloc |
---|---|---|---|---|
g++ -Weverything | N | N | N | N |
clang++ -Weverything | N | N | N | N |
cppcheck | Y | Y | Y | Y |
cpplint | N | N | N | N |
clang-tidy | Y | Y | Y | Y |
clang-analyze | Y | Y | Y | Y |
RidgeRun Resources | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||
Contact Us
|