美文网首页
10 C语言的妖怪!隐式声明

10 C语言的妖怪!隐式声明

作者: Savior2016 | 来源:发表于2019-03-11 13:10 被阅读0次

缘起

相传2019年3月8日女神节,天降暴雨。在一个年轻程序员的电脑里,发生了一件奇异的事……
他写了这样一个函数:

u32 UnionFloatToU32(float ordata)
{
  union convert
  {
    u32 u32data;
    float floatdata;
  } con;
  con.floatdata=ordata;
  return con.u32data;
}

函数内容不重要,主要是形参是float类型,这日后导致了悲剧的发生。
他进行了这样的调用:

void OSStackThread(mico_thread_arg_t arg)
{
  u32 ctest=0;
  double testfl=123.99;    //double是在测试过程中改的,本来是float,下面懒得重新截图,跟float现象是一样的
  UNUSED_PARAMETER(arg);
  while (true)
  {
      ctest=UnionFloatToU32(testfl);
      mico_thread_msleep(2000);
  }
}

什么?!他想把一个float直接放在一个32位的变量中存储起来?这……有什么价值?
这也不重要,重要的是悲剧就此发生了。
打断点,发现ctest是0?!


ctest

进函数看看:


形参
传进来的形参就是0?!
很灵异是不是,在网上查,很多人说float类型有问题,编译器有bug,建议使用全局变量传参。
直觉告诉我,他们是骗子。

真相只有一个

参考文献万恶之源:C语言中的隐式函数声明
简单点说,就是c编译器,遇到文件中可以找到的函数(暂时不清楚为什么不报函数未定义,编译器能在其他文件中找到),但是没有进行声明或者没有包含声明函数的头文件,这个时候,c编译器会自己给其增加一个固定格式的声明,以保证程序能够“顺利”完成编译(所以不能保证正常运行有啥用),然后警告你一下。
关键问题在于这个自行增加的声明,它只知道要给你声明形参,但是却不知道形参类型,只知道函数名以及你有几个形参。于是就根据你的调用情况,默认给你安排了int类型的形参(我感觉也可能是其他类型)。特别是把float安排错的时候,就会引发参数传递错误的问题。但是这个错误的值,经过我的多次试验,也不清楚为什么会成为0,有没有什么原理。如果谁知道了怎么回事麻烦告诉我一下。

避免办法

可以在工程上右键,重新编译工程,然后全选build框里面的编译信息.。复制到别的文件中,比如在vs code中新建一个文件,粘贴进去。
然后搜索declared implicitly就可以找到所有隐式声明的函数,再到提示中的文档里包含以下头文件或者添加一下声明就好了:

declared implicitly

相关文章

  • 10 C语言的妖怪!隐式声明

    缘起 相传2019年3月8日女神节,天降暴雨。在一个年轻程序员的电脑里,发生了一件奇异的事……他写了这样一个函数:...

  • c语言隐式函数声明

    一直觉得写了这么久代码,对c,或者c++的掌握还算不错,可是最近才发现,不了解的细节实在太多了。比如下面这个例子:...

  • Go 语言基础——变量常量的定义

    go语言不支持隐式类型转换,别名和原有类型也不能进行隐式类型转换go语言不支持隐式转换 变量 变量声明 声明变量不...

  • 当C语言隐式函数声明遇到printf

    最近在编程时遇到一个bug,通过gdb定位到printf函数,却怎么也找不到原因。从网上这篇博客中发现了问题所在:...

  • unity C# 自定义隐式转换

    在C#中类型转换类型:隐式转换(implicit conversions)隐式转换就是系统默认的、不需要加以声明就...

  • Kotlin的基础类型(一)

    声明变量 Kotlin是强类型语言,Kotlin要求所有的变量必须先声明后使用,声明变量时必须显式或隐式的指定变量...

  • 轻松掌握变量定义

    《代码大全2》阅读随笔 关闭隐式声明:隐式声明是一种危险的语言特性,可能带来意想不到的初始化数据,从而引起难以发现...

  • C语言的函数原型

    C 语言可以不使用函数原型,但是这样会导致编译器无法正确检查函数的参数数目和参数类型。例子如下: 出现隐式函数声明...

  • 03-数据类型转换

    数值类型转换 C语言中存在显式转换和隐式转换 Go语言中只有显式转换 Go语言中数值类型转换注意点 数值类型转换为...

  • Scala 隐式转换

    一、隐式转换 隐式转换需要执行隐式函数,隐式函数是以 implicit 关键字声明的带有单个参数的函数。隐式函数会...

网友评论

      本文标题:10 C语言的妖怪!隐式声明

      本文链接:https://www.haomeiwen.com/subject/fhwspqtx.html