C语言关于变量定义未使用编译警告warring

1.警告warring的产生

在日常写代码的过程中,定义的变量有时候只需要接收某个变量,仅仅对这个变量进行赋值,变量没有进行实际运算操作,这个时候编译器就会有警告。如果是这个原因导致的警告warring,你不处理也不会影响程序的运行。但是当你的工程所有编译的时候,总有几个warring影响你的最终结果,你要是个完美主义者或者是个处女座,总想解决这几个warring。

1.1具体警告warring

1.Keil MDK会有如下警告:

 **..main\main.c(36): warning:  #177-D: variable "i" was declared but never referenced
uint8_t i = 0;

2.IAR的编译警告信息:

Warning[Pe177]: variable "i" was declared but never referenced E:\Project\user\main.c 36 

告诉你在main.c源文件的第36行,有个变量i声明了但没有使用,这些编译的器的警告信息描述都是大同小异。

3.用gcc编译器,打开警告信息编译:

gcc test.c -o test -Wall

编译信息如下:

test.c: In function ‘main’:
test.c:6:6: warning: variable ‘a’ set but not used [-Wunused-but-set-variable]
  int a = 0;
      ^

告诉你在main.c源文件的第6行,有个变量a声明了但没有使用。

1.2解决方案

如何解决这个样的问题,这里给出两个解决方案(其实我也就只知道这两个,哈哈~~):

1.2.1利用attribute 机制

attribute 单词意思属性,就是用于配置变量或者代码段的属性。我们常用配置结构体的字节对齐,或者将代码编译到内存的固定地址。我们这里利用其中的一个属性__attribute__((unused))来表示这个变量可能会没有使用到,如下例子:

  1 #include <stdio.h>
  2
  3 int main(void)
  4 {
  5     int a __attribute__((unused));
  6
  7     return 0;
  8 }

就是告诉编译器变量a定义了,但有可能是不使用,所以编译器就不会有警告,因为你已经提前打过招呼了。

为了验证增加这个属性会不会对变量有所影响,我们将代码改回有警告的:

  1 #include <stdio.h>
  2
  3 int main(void)
  4 {
  5     //int a __attribute__((unused));
  6     int a;
  7
  8     return 0;
  9 }

我们可以将看编译后的反汇编文件进行对比发现文件都是一样的,如下是main函数部分的反汇编:

所以这两段的程序是一样的,增加属性并不会改变什么性质。

120 00000000004004d6 <main>:
121   4004d6:   55                      push   %rbp
122   4004d7:   48 89 e5                mov    %rsp,%rbp
123   4004da:   b8 00 00 00 00          mov    $0x0,%eax
124   4004df:   5d                      pop    %rbp
125   4004e0:   c3                      retq
126   4004e1:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
127   4004e8:   00 00 00
128   4004eb:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

1.2.2利用void关键字

void在C语言的作用,很多时候使用仅仅用于无参数返回,这只是一个很基本的功能。很多时候我们定义函数指针、NULL的时候,我们都会使用到void这个关键字。void的意思是空、无的意思,我们利用这个特性将变量操作一波,如下:

  1 #include <stdio.h>
  2
  3 int main(void)
  4 {
  5     //int a __attribute__((unused));
  6     int a;
  7     (void)(a);
  8     return 0;
  9 }

这里我们将变量a引用了一次,在前面增加(void),这样就能够避免编译器的警告,可以理解为告诉编译器我已经调用了这个变量,并且操作了它,这样编译器就不会有警告信息了。我们通过反汇编能够发现,这样操作以后,和前边attribute的是一样的,并不影响代码。

2.总结

最后我们得出结论,这两种花里胡哨的操作,其实不改变程序的任何执行,只不过是为了去除编译器的警告。正常使用的话会选择用void的比较多(就目前我发现),这个也比较好理解,因为我们写代码是给别人看的。通过这两种方法有没有发现C语言是越学越不懂,越学越有趣呢。最后的最后我们在编程的时候一定要做到0 error和0 warring,这样才是一名好的打工仔!!

  • 8
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_38042083

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值