C语言关于变量定义未使用编译警告warring 您所在的位置:网站首页 编译有警告是否需要处理 C语言关于变量定义未使用编译警告warring

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

2023-11-13 14:53| 来源: 网络整理| 查看: 265

C语言关于变量定义未使用编译警告warring 1.警告warring的产生1.1具体警告warring1.2解决方案1.2.1利用attribute 机制1.2.2利用void关键字 2.总结

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 2 3 int main(void) 4 { 5 int a __attribute__((unused)); 6 7 return 0; 8 }

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

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

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

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

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

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



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有