当前位置:网站首页>C语言中编译时出现警告C4013(C语言不加函数原型产生的潜在错误)
C语言中编译时出现警告C4013(C语言不加函数原型产生的潜在错误)
2022-08-01 07:37:00 【mary288267】
一 C语言中函数原型并不必要
一直以来用的是C++写程序,今天偶尔看到一段C程序,发现一个有趣的bug,现记录下来,备忘。
首先,C++在使用函数之前必须进行原型声明,否则无法编译通过。而C语言由于历史原因,函数原型声明在很多情况下并不是必须的。
- 在C89或C90(另一种名称叫ANSI C)规范中,函数声明并不是必须的;如果没有声明函数原型,函数的默认返回值为int,使用这种方式的原因是早期C程序的返回值大多是int 型的。C99不再支持函数的int类型为默认类型的设置。
- 在很多编译器中,并没有很好的支持C99标准。比如VS编译器,通过查看MSDN,可以知道VS的支持的是ANSI C,因此函数可以不加原型。
二 C语言不加函数原型产生的潜在错误
下面是个例子,演示了不加函数原型可能产生的一种错误。在VS中输入下面一段代码,文件后缀为.c,以保证编译为C程序。
#include <stdio.h>
int main()
{
int arg = 5;
float f = GetFloat(arg);
printf("\nf=%f", f);
return 0;
}
float GetFloat(int m)
{
double d = 2.0*m;
return d;
}
在编译过程中出现警告信息,提示GetFloat函数没有定义,假设外部返回int。
我们继续运行,查看最终结果
f的值是1,错了。为什么呢?我们查看汇编语言
我们可以看到,编译器认为GetFloat函数应该返回整形,因此用寄存器eax的值赋给了浮点数寄存器xmm0,然后再用xmm0赋值给栈上变量f。而GetFloat函数实际的返回值放在xmm0寄存器中,因此上述赋值当然错误。
作为对比,我们看看有原型时编译器会怎么处理。
此时,编译后知道GetFloat返回的是浮点值,因此返回值存储在xmm0寄存器中,所以编译器用xmm0给栈中变量f赋值。当然,这次一定是正确的了。
三 总结
由于很多编译器仍然使用的是ANSI C标准,因此,不声明原型的话,会误导编译器以为函数的返回值是int类型,尤其是使用库函数时,我们忘记加了头文件,而编译时又没报错,但运行时出现错误的运行结果。在编程中,务必避免。
另外,有一个经典案例,可供大家参考。
https://stackoverflow.com/questions/55454761/write-acces-violation-after-using-malloc-inside-a-function
边栏推荐
- VoLTE基础学习系列 | 什么是SIP和IMS中的Forking
- Summary of test points about app updates in different ways
- Generate pictures based on the content of the specified area and share them with a summary
- pytest接口自动化测试框架 | 集成Allure测试报告
- pytest interface automation testing framework | skip test classes
- Centos install php7.4, build hyperf, forward RDS
- pytest接口自动化测试框架 | parametrize源码解析
- 22 Niu Ke Duo School 1 I. Chiitoitsu (Probability dp)
- 并发编程13-JUC之CountDownLatch
- Golang: go static file processing
猜你喜欢
随机推荐
Upgrade to heavyweight lock, lock reentrancy will lead to lock release?
Zero-code website development tool: WordPress
The Bean's life cycle
R语言使用gt包和gtExtras包优雅地、漂亮地显示表格数据:gtExtras包的pad_fn函数与gt::fmt函数一起用于填充包含数值的特定列、对数据列的数值进行十进制对齐(从小数点对齐)
pytest接口自动化测试框架 | 跳过模块
国内外最顶级的8大plm项目管理系统
【手撕AHB-APB Bridge】~ AHB地址总线的低两位为什么不用来表示地址呢?
升级为重量级锁,锁重入会导致锁释放?
搜索框字符自动补全
Golang:go连接和使用mysql
日志导致线程Block的这些坑,你不得不防
Golang: go open web service
并发编程13-JUC之CountDownLatch
零代码网站开发利器:WordPress
【杭电多校第四场 B题】最短路图+缩点dp
Vim三种模式
pytest接口自动化测试框架 | 跳过测试类
How to use Photoshop to composite star trail photos, post-processing method of night sky star trail photos
阿里三面:MQ 消息丢失、重复、积压问题,该如何解决?
小程序全面屏手势配置案例