GCC 编译器警告——【-Wunused-variable】【-Wunused-parameter】

本文介绍了在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,world\n");
}

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 。报告完毕,请指示!
老师:出门左转!!!

其实,我们经常容易手误敲错代码,要命的是有时候并不会触发编译错误,但逻辑已经不对了。就像上面的代码段,我们需要秋 n1n2n3 的和,一不留神把 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 未使用。

总结:

  1. -Wall 选项仅仅能检测到未使用的局部变量,要检测未使用的函数参数,需要指定 -Wextra 选项。
  2. 编译器的警告选项最好打开,这能够帮助我们检查到很多问题。

微信搜索:编程笔记本。
微信搜索:编程笔记本。
微信搜索:编程笔记本。

gcc -Wall -Wextra -g -c cJSON_Parse.c -o cJSON_Parse.o cJSON_Parse.c:796:9: warning: "/*" within comment [-Wcomment] 796 | /*Parse_Wifi_Work_State parse_wifi_work_state; | gcc -Wall -Wextra -g -c cJSON.c -o cJSON.o gcc -Wall -Wextra -g -c link.c -o link.o gcc -Wall -Wextra -g -c main.c -o main.o main.c: In function ‘sendto_wifi_thread’: main.c:94:45: warning: unused variable ‘msg’ [-Wunused-variable] 94 | close(sockfd);char *msg = NULL; | ^~~ main.c:59:32: warning: unused parameter ‘arg’ [-Wunused-parameter] 59 | void *sendto_wifi_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘recv_m2001_thread’: main.c:115:31: warning: unused parameter ‘arg’ [-Wunused-parameter] 115 | void *recv_m2001_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘sendto_detect_thread’: main.c:149:34: warning: unused parameter ‘arg’ [-Wunused-parameter] 149 | void *sendto_detect_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘recv_driect_buffer_thread’: main.c:203:39: warning: unused parameter ‘arg’ [-Wunused-parameter] 203 | void *recv_driect_buffer_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘sendto_direct_thread’: main.c:211:34: warning: unused parameter ‘arg’ [-Wunused-parameter] 211 | void *sendto_direct_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘recv_direct_thread’: main.c:263:32: warning: unused parameter ‘arg’ [-Wunused-parameter] 263 | void *recv_direct_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘link_create_thread’: main.c:288:32: warning: unused parameter ‘arg’ [-Wunused-parameter] 288 | void *link_create_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘timeout_loop_thread’: main.c:403:33: warning: unused parameter ‘arg’ [-Wunused-parameter] 403 | void *timeout_loop_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘find_uid_thread’: main.c:411:29: warning: unused parameter ‘arg’ [-Wunused-parameter] 411 | void *find_uid_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘push_data_thread’: main.c:489:30: warning: unused parameter ‘arg’ [-Wunused-parameter] 489 | void *push_data_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘recv_o4_queue_thread’: main.c:620:14: warning: unused variable ‘send_o4_buffer’ [-Wunused-variable] 620 | char send_o4_buffer[1024] = ""; | ^~~~~~~~~~~~~~ main.c:615:34: warning: unused parameter ‘arg’ [-Wunused-parameter] 615 | void *recv_o4_queue_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘client_handle_thread’: main.c:691:34: warning: unused parameter ‘arg’ [-Wunused-parameter] 691 | void *client_handle_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘get_ip_handle_thread’: main.c:734:34: warning: unused parameter ‘arg’ [-Wunused-parameter] 734 | void *get_ip_handle_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘timer_handle_thread’: main.c:744:33: warning: unused parameter ‘arg’ [-Wunused-parameter] 744 | void *timer_handle_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘fn’: main.c:837:63: warning: unused parameter ‘fn_data’ [-Wunused-parameter] 837 | void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { | ~~~~~~^~~~~~~ main.c: In function ‘server_handle_thread’: main.c:1006:34: warning: unused parameter ‘arg’ [-Wunused-parameter] 1006 | void *server_handle_thread(void *arg) | ~~~~~~^~~ main.c: In function ‘recv_driect_buffer_thread’: main.c:206:1: warning: control reaches end of non-void function [-Wreturn-type] 206 | } | ^ main.c: In function ‘timeout_loop_thread’: main.c:409:1: warning: control reaches end of non-void function [-Wreturn-type] 409 | } | ^ main.c: In function ‘find_uid_thread’: main.c:437:1: warning: control reaches end of non-void function [-Wreturn-type] 437 | } | ^ main.c: In function ‘push_data_thread’: main.c:550:1: warning: control reaches end of non-void function [-Wreturn-type] 550 | } | ^ At top level: main.c:39:12: warning: ‘flags’ defined but not used [-Wunused-variable] 39 | static int flags = 0; | ^~~~~ gcc -Wall -Wextra -g -c mongoose.c -o mongoose.o gcc -Wall -Wextra -g -c o4_recv_queue.c -o o4_recv_queue.o gcc -Wall -Wextra -g -c pthread.c -o pthread.o pthread.c: In function ‘send_mail_msg’: pthread.c:137:26: warning: unused parameter ‘sendname’ [-Wunused-parameter] 137 | void send_mail_msg(char *sendname,char *ddata,char *recvname) | ~~~~~~^~~~~~~~ pthread.c: In function ‘recv_mail_msg’: pthread.c:148:53: warning: unused parameter ‘sendname’ [-Wunused-parameter] 148 | void recv_mail_msg(char *recvname,char *ddata,char *sendname) | ~~~~~~^~~~~~~~ gcc -Wall -Wextra -g -c queue.c -o queue.o gcc -Wall -Wextra -g cJSON_Parse.o cJSON.o link.o main.o mongoose.o o4_recv_queue.o pthread.o queue.o -o app -lpthread 利用上述makefile编译,为什么会出现这样的报错
07-05
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值