void f (int, int, int, bool, int *);
void g (int i)
{
f (1, 2, 3, &i, &i);
}
warning: the address of ‘i’ will always evaluate as 'true' [-Waddress]
-Warray-bounds:数组越界告警,如数组下标访问越界。
int array[3];
void foo(int n)
{
// 没有对入参进行校验,可能出现数组访问越界
for (int i = 0; i < n; ++i)
for (int j = 0; j < i; ++j)
if (array[i] == array[j])
array[i + j] = 0;
}
warning: array subscript is above array bounds [-Warray-bounds]
-Wbool-compare:布尔值与整形数据比较。
int
fn1 (int a, int b)
{
return ((a && b) <= 4);
}
warning: comparison of constant ‘4’ with boolean expression is always true[-Wbool-compare]
Wbool-operation:对布尔类型进行加减等操作。
int main(int argc, char **argv)
{
bool a = true;
bool b = a++;
bool c = ++b;
bool d = argc;
bool e = a & argc;
bool f = b | argc;
bool g = c ^ argc;
f &= argc;
g |= argc;
e ^= argc;
if (f1(argc))
e--;
else
--e;
if (!!argc)
return ((argv != NULL) ? d : ((f > g) ? e : (f << g)));
else
return f2(argc);
}
warning: increment of a boolean expression [-Wbool-operation]
#include<stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = 0; // ok just test\
c = a + b;
/*
* 这里我们期待c = 3
* /* 但实际上输出c = 0
*/
printf("the c is %d\n", c);
return 0;
}
warning: multi-line comment [-Wcomment]
sprintf(newname, "%s%s", dirname, basename);
warning: ‘.tmpconfig.’ directive writing 11 bytes into a region of size between 1 and 4097 [-Wformat-overflow=]
-Wformat-truncation :格式化字符串过程中可能导致截断错误。
struct S {
char b[3];
};
char buf[2];
void f(struct S const * s)
{
assert(strlen(s->b) == 1);
(void) snprintf(buf, sizeof (buf), "%s", s->b);
}
warning: ‘snprintf’ output may be truncated before the last format character[-Wformat-truncation=]
-Wint-in-bool-context:在应该使用布尔类型的地方,使用整形表达式。
for (a = 0; 1 << a; a++)
{}
warning: int in bool context [-Wint-in-bool-context]
#include<stdio.h>
add(int a, int b) { //函数没有声明返回类型
return a + b;
}
int test() {
int a = 0;
int b = 0;
int c = 0;
int d = 0;
c = add(a, b);
d = sub(a, b); //未声明sub的函数原型
return 0;
}
warning: return type defaults to `int' [-Wimplicit-int]
-Wimplicit-function-declaration:隐式声明(通常为函数遗漏了声明)。
#include<stdio.h>
add(int a, int b) { //函数没有声明返回类型
return a + b;
}
int test() {
int a = 0;
int b = 0;
int c = 0;
int d = 0;
c = add(a, b);
d = sub(a, b); //未声明sub的函数原型
return 0;
}
warning: implicit declaration of function `sub' [-Wimplicit-function-declaration]
-Winit-self:使用自身进行初始化。
int f()
{
int i = i;
return i;
}
warning: init 'i' with 'i' [-Winit-self]
int a;
…
if (!a > 1) { … }
warning: logic not used on the left hand of the comparision [-Wlogical-not-parentheses]
-Wmain:可疑的main函数类型检查。
#include <stdio.h>
void main ()
{
int x;
for(x=1;x<=10;x++)
{
printf("%d\n",x);
}
}
warning: function 'main' return type 'void', should be 'int' [-Wmain]
extern void dostuff(void);
int test(int arg1, int arg2)
{
int ret;
if (arg1) ret = arg2 ? 1 : 2;
dostuff();
if (arg1) return ret;
return 0;
}
warning: ‘ret’ may be used uninitialized in this function [-Wmaybe-uninitialized]
struct A {
A()
{
memset(&buff, 0xff, sizeof(buff));
}
int buff[0];
};
warning: 'memset' used with length equal to number of elements without multiplication by element size [-Wmemset-elt-size]
memset(buf, sizeof(buf), 0);
warning: 'memset' used with constant zero length parameter; this could be due to transposed parameters [-Wmemset-transposed-args]
#include <stdio.h>
int main(void)
{
int a = 1;
int b = 2;
if (a = b)
{
//do nothing
}
return 0;
}
warning: suggest parentheses around assignment used as truth value [-Wparentheses]
struct A {}
A test() {
A a = std::move(A()); // warn since A() is a pr-value
return std::move(a); // warn since a is a local variable
}
warning:move local variable in return statement [-Wpessimizing-move]
-Wpointer-sign:指针指向的内容分别为有符号和无符号类型。
#include <limits.h>
void foo(void) {
char *pc = 0;
#if CHAR_MIN < 0
/* plain char is signed but incompatible with signed char */
signed char *psc = pc;
#else
/* plain char is unsigned but incompatible with unsigned char */
unsigned char *puc = pc;
#endif
}
warning: pointer targets in initialization differ in signedness [-Wpointer-sign]
-Wreorder:初始化列表的初始化顺序与类成员声明的顺序不一致,会产生重排列。
class A
{
public:
A(int a, int b);
private:
int two;
int one;
}
A::A(int a, int b)
:one(a),
two(b)
{}
warning: 'A::one' will be initialized after [-Wreorder]
-Wrestrict:内存相关操作超出限制,导致截断或溢出。
#include <string.h>
struct S {
int n;
void * p;
};
void f(struct S * a, size_t n)
{
size_t i = 0, j = 0;
for (; i != n; ++i) {
if (a[i].n == 0) {
if (i != j) {
memcpy(&a[j], &a[i], sizeof (struct S));
}
++j;
}
}
}
warning: ‘memcpy’ accessing 16 bytes at offsets [0, 8] and [0, 8] overlaps between 8 and 16 bytes at offset [0, 8] [-Wrestrict]
int foo()
{
if(a==1)
{
return ok;
}
// no return here
}
warning: missing return statement [-Wreturn-type]
-Wsign-compare:无符号和有符号整形比较,会发生隐式转换。
int f (int i)
{
unsigned char c = i ? (-__SCHAR_MAX__ - 1) : 1U;
return c;
}
warning: signed and unsigned type in conditional expression [-Wsign-compare]
sizeof (ptr) / sizeof (ptr[0]) // 如果ptr不是数组,而是指针将产生告警
warning: division ‘sizeof (ptr) / sizeof (ptr[0])’ does not compute the number of array elements [-Wsizeof-pointer-div]
void f1(int *dst, int *src)
{ __builtin_memcpy(dst, src, sizeof(int *)); }
warning: argument to ‘sizeof’ in ‘__builtin_memcpy’ call is the same pointer type ‘int *’ as the destination; expected ‘int’ or an explicit length [-Wsizeof-pointer-memaccess]
#include <stdio.h>
int main()
{
int i;
int j;
for(i=32,j=2;i++;i<256)
{
if((i%16==0)
{
printf("\n%d:",j);
j++;
}
printf("%c ",i);
}
return 0;
}
warning: statement with no effect [-Wunused-value]
-Wunused-variable:变量定义后没有使用。
-Wvolatile-register-var:寄存器变量被修饰为volatile类型。
-Wzero-length-bounds:引用了大小为0的数组。
struct A { int n, a[0]; };
struct B { struct A a; int x; };
struct B b;
int f0 (void)
{
b.a.a[1] = 1;
int t = b.x;
b.a.a[1] = 0;
return b.x - t;
}
int f1 (struct B *p)
{
p->a.a[1] = 1;
int t = p->x;
p->a.a[1] = 0;
return p->x - t;
}
warning: array subscript 1 is outside the bounds of an interior zero-length array ‘int[0]’ [-Wzero-length-bounds]
-Wall,-Wextra开启的告警-Waddress:可能是无意义的地址使用方式(包括函数地址、变量地址等)。void f (int, int, int, bool, int *);void g (int i){ f (1, 2, 3, &i, &i);}warning: the address of ‘i’ will always evaluate as 'true' [-Waddress]-Warray-bounds:数组越界告警,如数组下标访问越界。in