[GCC]告警信息梳理

-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:数组越界告警,如数组下标访问越界。
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]
  • -Wc++11-compat -Wc++14-compat:版本兼容告警,如nullptr在C++11之前可以作为标识符使用,而在C++11之后,是关键字。
#define S(a) #a
const char* s = S(and);
warning: identifier "and" is a special operator name in C++[-Wc++11-compat]
  • Wcatch-value:try…catch…语句中的error部分用值而非引用捕获异常.
try
{
  new_idx = aReorderMap.at( orig_idx );
}
catch( std::out_of_range )
{
  new_idx = orig_idx;
}
warning: catching polymorphic type ‘class std::out_of_range’ by value [-Wcatch-value=]
  • -Wchar-subscripts:用有符号的char类型作为数组的下标。
int a[256];
int A(char c) { return a[c];      }
warning: array subscript has type ‘char’ [-Wchar-subscripts]
  • -Wcomment:注释语句中含有编译器预处理所需的特殊字符,使用-Wcomment会给出警告。不要小觑这些马虎代码,它很可能会影响程序的运行结果。
#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]
  • -Wduplicate-decl-specifier:声明语句有异议。
extern uint8_t CalculateChecksum(const communicationBlock_t const *messageBlock);
duplicate ‘const’ declaration specifier [-Wduplicate-decl-specifier]
  • -Wenum-compare:不同的枚举类型进行比较。
enum Magic {
  One, Two, Three
};
class Base {
public:
  virtual Magic GetType() = 0;
};
class ClassOne : public Base {
public:
  enum {
    MagicValue = One
  };
  Magic GetType() { return One; }
};
class ClassTwo : public Base {
public:
  enum {
    MagicValue = Two
  };
  Magic GetType() { return Two; }
};
template
<class Target>
Target* Cast( Base* from)
{
  if( from->GetType() != Target::MagicValue )
    throw new std::exception();
  return static_cast<Target*>( from );
}
void test()
{
  ClassOne obj;
  Cast<ClassOne>( &obj ); 
}
warning: comparison between 'enum Magic' and 'enum ClassOne::<anonymous>' [-Wenum-compare]
  • -Wenum-conversion:一个枚举类型隐式转换为另一个类型。
enum xpto
{
  A = 0,
  B = 1,
  X = 512
};
extern void print (unsigned int);
unsigned char bar (enum xpto a)
{
   return a;
}
warning: implicit conversion from enum to char [-Wenum-conversion]
  • -Wformat:检查printf和scanf等格式化输入输出函数的格式字符串与参数类型的匹配情况,如果发现不匹配则发出警告。某些时候格式字符串与参数类型的不匹配会导致程序运行错误,所以这是个很有用的警告选项。
int
ENTITYget_CORBAname (Entity ent)
{
    static char newname [BUFSIZ];
    strcpy( newname, ENTITYget_name(ent) );
    newname[0] = ToUpper (newname [0]);
    return newname;
}
fprintf(file, "\n//\t%s_ptr create_TIE();\n\tIDL_Application_instance_ptr create_TIE();\n", 
    ENTITYget_CORBAname(entity));
warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat]
  • -Wformat-overflow:格式化字符串可能造成缓冲区溢出,格式化字符串需要进行缓冲区溢出检查。
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]
  • -Wimplicit:-Wimplicit-int和-Wimplicit-function-declaration两个警告选项的集合,参见-Wimplicit-int,-Wimplicit-function-declaration
  • -Wimplicit-int:隐式的转化为整形类型。
#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]
  • -Wlogical-not-parentheses:逻辑没有显式的指明优先级,导致可能的符号优先级错误。
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]
  • -Wmaybe-uninitialized:变量声明后,在使用之前,经历了一些条件分支,其中有一些分支对该变量进行了赋值,另一些分支没有赋值。
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]
  • -Wmemset-elt-size:memset如果第一个参数引用一个数组,并且第三个参数是一个等于元素数的数字,但不等于内存中数组的大小,则警告对内置函数的可疑调用。这表明用户已经省略了元素大小的乘法。
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]
  • -Wmemset-transposed-args:memset使用时,第三个参数为0,而第二个参数非0,编译器认为可能是开发人员参数顺序填写错误触发此告警。
memset(buf, sizeof(buf), 0);
warning: 'memset' used with constant zero length parameter; this could be due to transposed parameters [-Wmemset-transposed-args]
  • -Wmisleading-indentation:当代码的缩进不反映块结构时发出警告。 具体而言,针对if , else , while和for子句发出警告,其中警告语句不使用大括号,后跟具有相同缩进的未保护语句。
  if (some_condition())
     foo();
     bar();  // Gotcha: this is not guarded by the "if".  
warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
  • -Wmissing-attributes:当函数声明缺少一个或多个属性时,产生告警。并且这种属性的缺少,可能会对生成的代码的正确性或效率产生负面影响。
__attribute__ ((noreturn)) void f (void) { __builtin_abort (); }
__attribute__ ((alias ("f"))) void fa (void);
void g (void) { }
__attribute__ ((alias ("g"), noreturn)) void ga (void);
warning: ‘fa’ specifies less restrictive attribute than its target ‘f’: ‘noreturn’ [-Wmissing-attributes]
  • -Wmissing-braces:如果聚合或联合初始值设定项没有完全包围,则发出警告。
int main()
{
  struct { int w; struct { int x, y; } ss; } s = { 1, .ss = 2, 3 };
  (void)s;
}
warning: missing braces around initializer [-Wmissing-braces]
  • -Wmultistatement-macros:不安全的宏定义。
#define DOIT x++; y++
if (c) DOIT;
warning: macro 'DOIT' not safe [-Wmultistatement-macros]
  • -Wnarrowing:缩窄转换,从int转为short可能会导致整形截断。
int i = -1;
char p = i;
warning: narrowing conversion '-1' from int to char [-Wnarrowing] 
  • -Wnonnull:向接受非空指针的函数传递了nullptr。
main()
{
  if(fork()==0)
  {
    printf("a");
    execlp("./file1",0);
    printf("b");
  }
  printf("c")
}
warning: null argument where non-null required (argument 2) [-Wnonnull]
  • -Wnonnull-compare:在已经标注了非空指针参数的函数中,再次判断是否为空。
void foo(int& x)
{
  bool b1 = (&x) == nullptr;
  bool b2 = &x == nullptr;
  int* ptr = &x;
  bool b3 = ptr == nullptr;
}
warning: nonnull argument ‘x’ compared to NULL [-Wnonnull-compare]
  • -Wopenmp-simd:采用openmp并行模型,被其他模型覆盖时,产生告警
  • -Wparentheses:如果在某些上下文中省略了括号,例如当预期是bool值,却进行了赋值运算时,或者运算符嵌套。
#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]
  • -Wpessimizing-move:不规范的std::move用法,例如在return语句中对局部变量进行move操作。
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]
  • -Wreturn-type:函数有返回值,但函数体个别地方没有返回值(特别是有if判断,可能忘记在else添加返回值)。
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]
  • -Wsizeof-pointer-div:使用除法求数组元素大小,sizeof (ptr) / sizeof (ptr[0]),如果ptr是指针,而非数组。
sizeof (ptr) / sizeof (ptr[0])  // 如果ptr不是数组,而是指针将产生告警
 warning: division ‘sizeof (ptr) / sizeof (ptr[0])’ does not compute the number of array elements [-Wsizeof-pointer-div]
  • -Wsizeof-pointer-memaccess:对指针类型进行sizeof运算,作为内存操作函数的大小参数。
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]
  • -Wstrict-aliasing:对违反strict-aliasing规则的代码产生告警,例如将一个float类型的指针,指向一块存储了整形数字的内存空间。
  • -Wstrict-overflow:
void ABSTest(int64_t value1) {
  uint64_t value = static_cast<uint64_t>(value1 < 0 ? 0 - value1 : value1);
  std::cout << "value " << value;
  if (value < 2ul)
      std::cout << " less than " << 2 << "?!\n";
  else
      std::cout << " compare correct\n";
}
int main()
{
  int64_t value1 = std::numeric_limits<int64_t>::min();
  ABSTest(value1);
}
warning: assuming signed overflow does not occur when simplifying conditional [-Wstrict-overflow]
  • -Wswitch:switch语句检查某个枚举类型,但是没有用case列出该枚举类型所有的枚举值或switch没有default时。
  • -Wtautological-compare:对于比较结果恒定为true或false的语句进行告警。
int i = 1;
if (i > i) 
{ … }
warning: if always equals to false [-Wtautological-compare]
  • -Wtrigraphs:存在会被编译器替换的三字符组。
int main(int argc, char **argv) ??<
        char buf??(100??) = ??< 0 ??>;
        printf("??/ ??' ??( ??) ??! ??< ??> ??-\n");
        return 0;
??>
warning: trigraph ??= ignored, use -trigraphs to enable [-Wtrigraphs]
  • -Wuninitialized:变量在使用前未初始化。
  • -Wunknown-pragmas:未知的#pragma语句,例如在gcc中使用vc++语法。
#pragma comment(lib,"winmm.lib")
warning: ignoring #pragma comment [-Wunknown-pragmas]
  • -Wunused-function:声明但未使用函数。
  • -Wunused-label:未使用的标签,未使用的标签,比如用goto会使用label,但在删除goto语句时,忘了删除label。
  • -Wunused-value:表达式或函数有返回值,但是未被使用。
#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]
  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值