【gcc】warning信息梳理

gcc warning信息梳理

-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]
    
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ʚ兔子的先森ɞ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值