• C++里消除Wunused


      编译程序时,有一大堆警告总是不爽的。别人的代码也就忍了,不好去改。自己的可没法忍。看看C++里怎么消除Wunused警告。

      先来看下面的程序:

    #include <iostream>
    
    
    int main(int argc,char **argv)
    {
        int  a;
    
        return 0;
    }

    编译的时候,打开所有的警告:

    xzc@xzc-HP-ProBook-4446s:~/code/test$ g++ -g -W -Wall -o unused unused.c
    unused.c: In function ‘int main(int, char**)’:
    unused.c:19:10: warning: unused variable ‘a’ [-Wunused-variable]
         int  a;
              ^
    unused.c: At global scope:
    unused.c:17:5: warning: unused parameter ‘argc’ [-Wunused-parameter]
     int main(int argc,char **argv)
         ^
    unused.c:17:5: warning: unused parameter ‘argv’ [-Wunused-parameter]

    可以看到,没有使用的变量、参数都给出了警告。警告是编译器给的,我们当然可以把编译选项中的-W -Wall去掉一了百了。可通常我们只是想告诉编译器:这个地方是我故意这样写的,不用警告我。其他地方有问题才警告我。那么就来看看编译器的__attribute__((unused))属性。这个属性可以在声明变量时指定变量是不需要用到的,不需要警告。如:

    #include <iostream>
    
    
    int main(int argc,char **argv)
    {
        int  a __attribute__((unused));
    
        return 0;
    }

    编译时就不会再提示变量a未使用:

    xzc@xzc-HP-ProBook-4446s:~/code/test$ g++ -g -W -Wall -o unused unused.c
    unused.c:17:5: warning: unused parameter ‘argc’ [-Wunused-parameter]
     int main(int argc,char **argv)
         ^
    unused.c:17:5: warning: unused parameter ‘argv’ [-Wunused-parameter]

    对__attribute__((unused))稍微包装一下,就有了网上广为流传的版本:

    #ifdef UNUSED
    #elif defined(__GNUC__)
    # define UNUSED(x) UNUSED_ ## x __attribute__((unused))
    #elif defined(__LCLINT__)
    # define UNUSED(x) /*@unused@*/ x
    #else
    # define UNUSED(x) x
    #endif
    
    #include <iostream>
    
    
    int main(int UNUSED(argc),char **UNUSED(argv))
    {
        int  UNUSED(a);
    
        return 0;
    }

    这样编译时就完全没有警告了。不过,如果有人没注意看你的代码,又使用变量a,则会提示error: ‘a’ was not declared in this scope。

      上面的方法是GNUC里提供的,而Qt里有一个Q_UNUSED,它的实现在qglobal.h里。

    #ifndef Q_TYPENAME
    #  define Q_TYPENAME typename
    #endif
    
    //
    // Use to avoid "unused parameter" warnings
    //
    #define Q_UNUSED(x) (void)x;
    
    //
    // Debugging and error handling
    //
    
    #if !defined(QT_NO_CHECK)
    #  define QT_CHECK_STATE            // check state of objects etc.
    #  define QT_CHECK_RANGE            // check range of indexes etc.
    #  define QT_CHECK_NULL                // check null pointers
    #  define QT_CHECK_MATH                // check math functions
    #endif

    当然,我们也可以按它的方式去做,不过它是在使用的时候(声明一个int (void)a可以编译通过,在函数的参数里则不行),而GNUC方法是在声明的时候。按Qt的方法:

    #define UNUSED(x) (void)x
    
    #include <iostream>
    
    
    int main(int argc,char **argv)
    {
        int  a;
    
        UNUSED(a);
        UNUSED(argc);
        UNUSED(argv);
        
        return 0;
    }

    这样编译也是没有警告的。

      上面两种方法处理后,用 g++ -S unused.c生成汇编代码来对比,与下面的程序是一致的,不会生成多余的代码,没有效率的问题:

    #include <iostream>
    
    
    int main()
    {
    int a;
    return 0; }
  • 相关阅读:
    [bzoj4197][Noi2015]寿司晚宴
    [bzoj3531][Sdoi2014]旅行
    [洛谷P1430]序列取数
    [洛谷P2044][NOI2012]随机数生成器
    [洛谷P2839][国家集训队]middle
    [洛谷P3937]Changing
    [bzoj3532][Sdoi2014]Lis
    [洛谷P2590][ZJOI2008]树的统计
    [洛谷P4311]士兵占领
    [洛谷P1879][USACO06NOV]玉米田Corn Fields
  • 原文地址:https://www.cnblogs.com/coding-my-life/p/4175761.html
Copyright © 2020-2023  润新知