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

  先来看下面的程序:

  1. #include <iostream>
  2.  
  3. int main(int argc,char **argv)
  4. {
  5. int a;
  6.  
  7. return ;
  8. }

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

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

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

  1. #include <iostream>
  2.  
  3. int main(int argc,char **argv)
  4. {
  5. int a __attribute__((unused));
  6.  
  7. return ;
  8. }

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

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

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

  1. #ifdef UNUSED
  2. #elif defined(__GNUC__)
  3. # define UNUSED(x) UNUSED_ ## x __attribute__((unused))
  4. #elif defined(__LCLINT__)
  5. # define UNUSED(x) /*@unused@*/ x
  6. #else
  7. # define UNUSED(x) x
  8. #endif
  9.  
  10. #include <iostream>
  11.  
  12. int main(int UNUSED(argc),char **UNUSED(argv))
  13. {
  14. int UNUSED(a);
  15.  
  16. return ;
  17. }

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

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

  1. #ifndef Q_TYPENAME
  2. # define Q_TYPENAME typename
  3. #endif
  4.  
  5. //
  6. // Use to avoid "unused parameter" warnings
  7. //
  8. #define Q_UNUSED(x) (void)x;
  9.  
  10. //
  11. // Debugging and error handling
  12. //
  13.  
  14. #if !defined(QT_NO_CHECK)
  15. # define QT_CHECK_STATE // check state of objects etc.
  16. # define QT_CHECK_RANGE // check range of indexes etc.
  17. # define QT_CHECK_NULL // check null pointers
  18. # define QT_CHECK_MATH // check math functions
  19. #endif

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

  1. #define UNUSED(x) (void)x
  2.  
  3. #include <iostream>
  4.  
  5. int main(int argc,char **argv)
  6. {
  7. int a;
  8.  
  9. UNUSED(a);
  10. UNUSED(argc);
  11. UNUSED(argv);
  12.  
  13. return ;
  14. }

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

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

  1. #include <iostream>
  2.  
  3. int main()
  4. {
    int a;
  5. return ;
  6. }

C++里消除Wunused的更多相关文章

  1. C语言博客作业05——指针

    1.本章学习总结 1.1思维导图 1.2本章学习体会及代码量 1.2.1学习体会 可能因为之前数组那块儿的作业拖得太久了,以至于我觉得指针学的好快,还没反应过来就教完了,然后一开始做题的时候,就是一脸 ...

  2. PostgreSQL 数据库错误代码解释

    PostgreSQL 服务器发出的所有消息都赋予了五个字符 的错误代码, 这些代码遵循 SQL 的 "SQLSTATE" 代码的习惯.需要知道发生了什么错误条件的应用通常应该测试错 ...

  3. PostgreSQL 数据库错误状态编号解释[附带列表

    PostgreSQL 服务器发出的所有消息都赋予了五个字符的错误代码, 这些代码遵循 SQL 的 "SQLSTATE" 代码的习惯.需要知道发生了什么错误条件的应用通常应该测试错误 ...

  4. sql server 基础语法2

    别名,选择,查询,排序,去重,筛选 select * from UserInfo as ui --起别名 select UserName,UserPwd --指定选择的列 from UserInfo ...

  5. 策略枚举:消除在项目里大批量使用if-else的正确姿势

    文/朱季谦 想起刚开始接触JAVA编程的时候,若遇到大量流程判断语句,几乎满屏都是if-else语句,多得让自己都忘了哪里是头,哪里是尾,但是,纵然满屏是if-else,但彼时也没有觉得多别扭.等到编 ...

  6. CELERY里,这个WARNING如何消除?

    原来命令行里有提示,保证用-n给与不同的名字即可. 比如: [program:celeryd]command=/usr/local/python27/bin/celery worker --app=s ...

  7. 使用JS如何消除一个数组里重复的元素

    JS: var arrData = [1,3,5,7,7,8,9,3,10,8,"sdsdsds","sss","ffff","s ...

  8. Linux环境下shell和vim中乱码原因及消除办法

    shell和vim中乱码原因及消除办法 作者:Jack47 在Linux下开发,经常遇到乱码问题:shell或者vim中显示不了中文,或者能够显示,但不能输入中文.每次都是上网去搜,或者同事告诉我一些 ...

  9. Linq to sql 有什么办法可以实现消除列重复?

    比如数据库里有一表,有两个字段:ID User1 小白2 小红3 小白 过滤User列为小白的重复项后,我想要得到:ID User1 小白2 小红 如果写db.linq.customer.Distin ...

随机推荐

  1. 左侧高亮(js)

    //左导航高亮 (function(){ var leftnav = $('#leftnav');  //左侧ul var pi = __preset.curpathid; if(pi=='/acco ...

  2. Perl 多线程模块 Parallel::ForkManager

    Perl 多线程模块 Parallel::ForkManager 一个简单的并行处理模块.这个是用来对付循环的多线程处理. 放在循环前面. Table of Contents 1 Synops内容简介 ...

  3. 在CentOS 7上利用systemctl加入自己定义系统服务

    CentOS 7继承了RHEL 7的新的特性,比如强大的systemctl,而systemctl的使用也使得以往系统服务的/etc/init.d的启动脚本的方式就此改变,也大幅提高了系统服务的执行效率 ...

  4. Qt 界面使用自己定义控件 &quot;提升为&quot;

    1.效果图 我做了一个很easy的样例,一个能够显示颜色的QLabel,边上有个button,点击,跳出颜色选取的Dialog,然后选择一个颜色.这个QLabel会变成什么颜色. 2.ColorLab ...

  5. Hadoop集群运行JNI程序

    要在Hadoop集群运行上运行JNI程序,首先要在单机上调试程序直到可以正确运行JNI程序,之后移植到Hadoop集群就是水到渠成的事情. Hadoop运行程序的方式是通过jar包,所以我们需要将所有 ...

  6. [转] iOS使用NSMutableAttributedString 实现富文本(不同颜色字体、下划线等)

    转自: 在iOS开发中,常常会有一段文字显示不同的颜色和字体,或者给某几个文字加删除线或下划线的需求.之前在网上找了一些资料,有的是重绘UILabel的textLayer,有的是用html5实现的,都 ...

  7. JavaScript 对象 - 与属性的相关知识

    function inherit(p){ if(p == null) throw TypeError(); if(Object.create) return Object.create(p); var ...

  8. TFS 用户与组管理(转)

    作者:frank.liu kaka.zhou 安装 Team Foundation Server 后,会创建以下全局组.可以使用这些全局组来控制 Team Foundation 用户的权限. 组 权限 ...

  9. Android之Activity启动的源码简介

    从一个简单的startActivity开始 进入了Activity.java public void startActivity(Intent intent) { this.startActivity ...

  10. 《第一行代码》学习笔记11-活动Activity(9)

    1.android:theme,是用于给当前活动指定主题的,Android系统内置很多主题可以选择,@android:style/Theme.Dialog则是 让DialogActivity使用对话框 ...