http://xifage.com/gcc-4-6-warning-variable-set-but-not-used/




Fedora 15 安装后,GCC 版本号升级至 4.6:


$ gcc --version

gcc (GCC) 4.6.0 20110530 (Red Hat 4.6.0-9)
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.




官网给出了这次的升级内容(传送门)。


注意到下面这一条:


  • New -Wunused-but-set-variable and -Wunused-but-set-parameter warnings were added for C, C++, Objective-C and Objective-C++. These warnings diagnose variables respective parameters which are only set in the code and never otherwise used. Usually such variables are useless and often even the value assigned to them is computed needlessly, sometimes expensively. The -Wunused-but-set-variable warning is enabled by default by -Wall flag and -Wunused-but-set-parameter by -Wall -Wextra flags.

 


  • (解释)对C、C++、Objective-C 和 Objective-C++ 增加了两个 新的 warning 类型:-Wunused-but-set-variable-Wunused-but-set-parameter。当程序中出现已经赋值的但并未使用过的变量时,GCC会触发 -Wunused-but-set-variable 的警告;当程序中某个函数参数没有在函数中使用过时,GCC会触发 -Wunused-but-set-parameter 警告。这两个警告可以用 -Wall 和 -Wall -Wextra 分别启用。

 


下面是一个实验程序,用于显示两种类型的警告。


1 2 3 4 5 6 7 8 9 10 11 12 13 
void test(int x) { }   int main() {        int a, b;     a = 1;     b = 2;     test(b);       return 0; }

 


运行下面 3 条命令,得到不同结果:


1. 不带任何编译选项,没有 warning 提示:


$ gcc variable_set_warning.c -o variable_set_warning


2. 只带 -Wall 选项,有 -Wunused-but-set-variable 警告:


$ gcc -Wall variable_set_warning.c -o variable_set_warning

variable_set_warning.c: In function ‘main’:
variable_set_warning.c:7:9: warning: variable ‘a’ set but not used [-Wunused-but-set-variable]



3. 带 -Wall -Wextra 选项,有 -Wunused-parameter 和 -Wunused-but-set-variable警告:


$ gcc -Wall -Wextra variable_set_warning.c -o variable_set_warning

variable_set_warning.c: In function ‘test’:
variable_set_warning.c:1:15: warning: unused parameter ‘x’ [-Wunused-parameter]
variable_set_warning.c: In function ‘main’:
variable_set_warning.c:7:9: warning: variable ‘a’ set but not used [-Wunused-but-set-variable]



实验完毕。


结论:这个改进可以帮助程序开发者减少某些低级错误的发生,将更多的精力投入到算法的开发上。


但是:有时候开发者需要在调试过程中定义一些虽已赋值,但并不使用的变量,或者定义一些在后续版本中要使用到的函数参数。可又不能不用 -Wall -Wextra 这两个选项来编译。


解决方法

下面是 GCC Manual 里提到的解决方法:


“To suppress this warning use the unused attribute.”


也就是说我们可以修改出现 warning 的变量和参数的 attribute 来避免上述 warning 的发生。


将上面的程序修改如下:


1 2 3 4 5 6 7 8 9 10 11 12 13 
void test(int __attribute__ ((unused)) x) { }   int main() {        int __attribute__ ((unused)) a, b;     a = 1;     b = 2;     test(b);       return 0; }

 


要修改属性的变量前加入以两个下划线开头和结尾的 attribute 关键字,并在后面的 unused 关键字两边加上两层括号


注意: int __attribute__ ((unused)) a, b; 这一行可以同时修改 a 和 b 的 attribute。


这时用下面的命令编译上面的 C 程序:


$ gcc -Wall -Wextra variable_set_warning_suppressed.c -o variable_set_warning_suppressed


是会无警告编译通过的。


但是,这一方法的缺点是只能用 GCC 来编译程序时,才可以使用修改 attribute 的方法,这就丧失了可移植性。你可以用条件编译的办法来对其进行改进,添加一个宏来决定采用什么编译器编译。


 


相关资料:


http://www.embedded-bits.co.uk/tag/gcc-attribute/


http://gcc.gnu.org/gcc-4.6/changes.html


http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#Function-Attributes


http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes


 

    全站熱搜

    立你斯 發表在 痞客邦 留言(0) 人氣()