0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言-函数未声明引发的怪异现象

嵌入式那些事 来源:嵌入式那些事 2023-04-04 09:36 次阅读

1.问题描述

最近进行ARM嵌入式系统开发过程中遇到一个问题,就是打印浮点数据不正确。这里的打印函数在其他文件定义的,在main.c中调用了打印函数,但是并没有include打印函数的头文件,编译能够正确的编译过去,但是打印浮点数据时浮点数据的内容始终不正确,比如kprintf("float_num:%f ", 12.06);实际显示的内容可能是0.0000。

最开始以为浮点的堆栈处理问题,后来检查浮点的入栈和出栈并没有什么问题,后来调试发现kprintf("float_num:%f ", 12.06);这句代码的汇编格式使用d0在保存浮点数据,正常来说ARM传递参数使用的是r0,r1,r2,r3寄存器或者堆栈,这明显就不对,采用的貌似是编译器的通用参数处理方式。当然了导致这个问题的原因就是kprintf这个函数并未声明,因为kprintf函数未声明,编译器在编译当前文件时,并不知道kprintf函数的参数及顺序,因此采用的貌似是编译器的通用参数处理方式。

kprintf函数未声明时,kprintf("float_num:%f ", 12.06);对应的汇编代码为:

vldrd0,[pc,#188]
ldrr0,[pc,#200]
blkprintf

kprintf函数在main.c文件中声明了时,kprintf("float_num:%f ", 12.06);对应的汇编代码为:

addr3,pc,#252
ldrdr2,r3,[r3]
ldrr0,[pc,#188]
blkprintf

函数未声明除了造成上述问题之外(参数传入的不正确导致结果出错),也可能导致结果正确,但是返回的结果不正确(比如一个函数返回double型的结果,如果函数未声明就使用,可能会返回4字节的结果,导致结果返回错误)。

函数未声明时,kprintf("int_num:%d ", 15);能够正确的显示,因为此时15这个值能够通过普通寄存器(r0/r1/r2/r3)传递,因此不会出现打印浮点数的问题。如果传递的参数或者返回的值,不能通过普通寄存器(r0/r1/r2/r3)传递时,就可能出现奇怪的问题了。

2.问题解决方法

解决这个问题的方法自然是,在使用到kprintf的文件中include打印函数kprintf的头文件。

3.小结

对于开发过程中,如果编译时提示"warning: implicit declaration of function 'xxx'"这类的信息,一定还是加上这些函数的声明。如果不添加函数声明,编译虽然能够通过,但是遇到我上面提及的怪异问题,调试可能都不知如何下手,谨记吧。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ARM
    ARM
    +关注

    关注

    134

    文章

    8653

    浏览量

    361831
  • 嵌入式
    +关注

    关注

    4983

    文章

    18286

    浏览量

    288509
  • C语言
    +关注

    关注

    180

    文章

    7533

    浏览量

    128790
  • 函数
    +关注

    关注

    3

    文章

    3882

    浏览量

    61310
  • 编译
    +关注

    关注

    0

    文章

    615

    浏览量

    32397

原文标题:C语言-函数未声明引发的怪异现象

文章出处:【微信号:嵌入式那些事,微信公众号:嵌入式那些事】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    为什么中断函数声明也可以

    C写中断函数时,为什么不声明也可以用,以前我记得C语言老师说过在调用一个自定义函数以前要进行
    发表于 11-26 00:08

    解读C声明C基础

    返回值为int 的函数的指针;          C语言声明不能从左往右按顺序解读;而是左右来回地解读;基本类型和派生类型:  int(*func_table[10])(inta
    发表于 01-22 16:05

    编译后提示这个函数未声明

    编译后提示这个函数未声明function "InitXintf" declared implicitly FLASH.c /lab14-39VF800/SRC line 16 C/
    发表于 08-30 11:03

    为什么编译时有Warning说这个函数有定义未声明

    在LWIP1.3里面dns.c里面有定义了一个static u32_t dns_lookup(const char *name){。。。。}并且在dns.h里面进行了声明static u32_t dns_lookup(const char *name);为什么编译时有Wa
    发表于 10-30 22:29

    C语言中一个括号引发的……

    C语言中一个括号引发的……作者:薛定谔的coding猫今天给大家带来一个比较典型的问题,一个小括号引发的bug,问题虽小但值得注意。首先来看如下代码· · if (x == 0)if
    发表于 05-19 14:06

    C语言函数声明、形参和实参分别是什么

    例1:#include void g(void){printf("hello,函数!\n");}int main(){g();return 0;}例2:#include void f(void);//函数声明,分号不能丢int
    发表于 07-15 07:34

    【原创】STM32 C语言函数”深入剖析

    单片机C语言函数,我们首先要明确函数是一个什么东东?C语言为什么要使用
    发表于 07-20 12:09

    从ESP12F的Arduino IDE编译源代码时,出现“BearSSL尚未声明”错误是怎么回事?

    当我尝试从 ESP12F 的 Arduino IDE 编译我的源代码时,出现“BearSSL 尚未声明”错误。我正在尝试使用 BearSSL 进行 OTA 更新。请告知我是否需要更新任何库。
    发表于 02-24 08:32

    在nuclei studio中编译遇到的两个问题,计数模块显示未声明和如何在c工程中添加硬件描述语言

    core_feature_base.h,却可以在编译的时候使用core_feature_base.h声明计数模块函数 2.使用nice接口的Verilog文件 可以与c语言软件程序一
    发表于 08-16 07:06

    剖析什么是C语言中的隐式函数声明

    「1、什么是C语言的隐式函数声明」 在C语言中,函数在调用前不一定非要声明。如果没有
    的头像 发表于 05-25 09:38 3324次阅读
    剖析什么是C<b class='flag-5'>语言</b>中的隐式<b class='flag-5'>函数</b><b class='flag-5'>声明</b>

    51单片机实战教程之C语言基础(五 C语言函数及其定义)

    虽然部分C语言函数的返回值与其参数存在对应关系,但是它与数学里的函数不是同一概念。有的书上把它定义为完成特定任务的代码集合。 C语言函数
    发表于 11-21 09:51 31次下载
    51单片机实战教程之C<b class='flag-5'>语言</b>基础(五 C<b class='flag-5'>语言</b><b class='flag-5'>函数</b>及其定义)

    C语言-函数的定义、声明、传参

    C语言函数是非常重要的知识点,一个完整的C语言程序就是由主函数和各个子函数组成的,主函数调用子
    的头像 发表于 08-14 09:57 1630次阅读

    隐式函数声明会导致系统怎么样?

    在C语言中,函数在调用前不一定非要声明被调用的函数。如果没有声明的话,那么编译器会自动按照一种隐式声明
    的头像 发表于 02-15 15:02 648次阅读

    C语言内部函数与外部函数介绍

    一般为了叙述方便,把建立存储空间的声明称定义,而把不需要建立存储空间的声明称为声明。 在函数中出现的对变量的声明,除了用extern
    的头像 发表于 03-10 14:36 845次阅读