GCC 编译器警告——【-Wunused-variable】【-Wunused-parameter】
点击上方蓝字关注我,我们一起学编程
欢迎小伙伴们分享、转载、私信、赞赏
微信搜索:编程笔记本。
微信搜索:编程笔记本。
微信搜索:编程笔记本。
昨天在 review 同事的一个 MR 时,发现了一个比较有趣的问题,记录如下。
同时的 MR 修复的大概是这样一个问题:函数内部定义的某些局部变量仅用于 Log 语句,当 Log 关闭时,这些局部变量在整个函数作用域内就都未被使用过,所以在编译的时候就会报**变量未使用
**的警告信息。
程序中的 Log 语句主要是帮助开发人员调试程序的,主要是打印一些程序运行的中间状态和提示信息。所以在一般的生产环境,特别是在内存比较有限的场景下,通常都是关闭 Log 的。
场景还原:
#include <stdio.h>
#define DEBUG_CONTEXT
void fun(void)
{
int age = 1;
#ifdef DEBUG_CONTEXT
printf("The age is %d.n", age);
#endif
}
int main()
{
fun();
return 0;
}
Tips: 需要打开编译器的警告选项,才能输出编译器警告。笔者使用的是 gcc 编译器,相应的警告选项为
-Wall
。
下面我们来编译运行一下:
➜ $ gcc -Wall test.c -o test
➜ $ ./test
The age is 1.
微信搜索:编程笔记本。
微信搜索:编程笔记本。
微信搜索:编程笔记本。
如果我们将 Log 语句删除以减小程序体积,我们可以删除用于控制调制的宏:#define DEBUG_CONTEXT
。这样,printf
语句将不会出现在可执行文件中。此时,局部变量 age
就成了未使用的局部变量。
#include <stdio.h>
//#define DEBUG_CONTEXT
void fun(void)
{
int age = 1;
#ifdef DEBUG_CONTEXT
printf("The age id %d.n", age);
#endif
}
int main()
{
fun();
return 0;
}
再来编译运行一下:
➜ $ gcc -Wall test.c -o test
test.c:7:9: warning: unused variable 'age' [-Wunused-variable]
int age = 1;
^
1 warning generated.
可以看到,由于 printf
不再存在,局部变量 age
就未被使用,所以编译时就会出现 -Wunused-variable
警告。
看到这里,小伙伴是不是以为就结束啦?哈哈哈,下面才是今天的主题哦,且看!
微信搜索:编程笔记本。
微信搜索:编程笔记本。
微信搜索:编程笔记本。
对汇编了解的朋友都知道,函数传入的参数也属于当前函数作用于内的“局部变量”。但我仔细回想了一下,有的时候,我们未使用函数传入的参数好像并没有什么问题啊?
再来测试一下:
#include <stdio.h>
void fun(int num)
{
printf("Hello,worldn");
}
int main()
{
fun(0);
return 0;
}
编译:
➜ $ gcc -Wall test.c -o test
➜ $
可以看到,未使用函数传入的参数并没有报出警告。
最终,在查阅 gcc 文档后,找到根本原因:
In order to get a warning about an unused function parameter, you must either specify -Wextra -Wunused (note that -Wall implies -Wunused), or separately specify -Wunused-parameter.
原来,函数传入的参数有一个其他的名称:function parameter 。从 gcc 文档可以知道,要想报出这样的警告,需要指定 -Wextra
选项。
再来测试一下:
➜ $ gcc -Wextra test.c -o test
test.c:3:14: warning: unused parameter 'num' [-Wunused-parameter]
void fun(int num)
^
1 warning generated.
果然,这时候未使用的函数参数给出了警告信息 -Wunused-parameter
。
不知道,会不会有小伙伴有这样的疑问:这样的警告信息有什么用呢?
哈哈,看看下面的代码段你就知道啦!
#include <stdio.h>
int add(int n1, int n2, int n3)
{
return n1 + n2 + n2;
}
int main()
{
int sum = add(1, 2, 3);
printf("The sum is %d.n", sum);
return 0;
}
有一天,你需要写一个三个数求和的功能,于是你编辑、编译、运行一气呵成,熟练得让人心疼~
➜ $ gcc test.c -o test
➜ $ ./test
The sum is 5.
你:报告老师,
1 + 2 + 3 = 5
。报告完毕,请指示!
老师:出门左转!!!
其实,我们经常容易手误敲错代码,要命的是有时候并不会触发编译错误,但逻辑已经不对了。就像上面的代码段,我们需要秋 n1
、n2
和 n3
的和,一不留神把 n3 写成了 n2 。虽然程序不会报错,但是程序已经完全不对了。如果我们打开警告选项,就不会出现这种低级错误了。
➜ $ gcc -Wextra test.c -o test
test.c:3:29: warning: unused parameter 'n3' [-Wunused-parameter]
int add(int n1, int n2, int n3)
^
1 warning generated.
编译器会提示我们,函数参数 n3 未使用。
总结:
-
-Wall
选项仅仅能检测到未使用的局部变量,要检测未使用的函数参数,需要指定-Wextra
选项。 - 编译器的警告选项最好打开,这能够帮助我们检查到很多问题。
微信搜索:编程笔记本。
微信搜索:编程笔记本。
微信搜索:编程笔记本。