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,这样才是一名好的打工仔!!