技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 编程语言 --> 为什么C语言需要函数声明

为什么C语言需要函数声明

浏览:4750次  出处信息

   C语言使用函数前为什么要声明是个老问题了,还是没忍住想简单记一下,事情原于同事写的一段测试代码。

   前两天同事拿来一段C代码让我帮忙看下,main()函数里面调用了一个另一个函数,该函数返回double值,在函数内部return之前printf打印出来的返回值和在函数调用后的返回值差别非常大,我刚开始迷迷呼呼还奇怪了半天,后来把编好的binary反汇编看了一眼就知道怎么回事了,假设函数名是func,在汇编代码的main代码块里面发现这样一句话:

callq  400550 <func>
cvtsi2sd %eax,%xmm0

   我次凹,这是怎么回事,x86_64汇编不是浮点型返回值不是会直接放在xmm0寄存器里面吗,为什么还会有一条奇怪的cvtsi2sd这样的指令,于是就意识到main代码块和func函数没有在一个c文件里面,而在编译的时候两个源文件是单独进去编译的,在编译完成后才会由链接器把目标文件链接起来,这也就是为什么声明是必须的,如果函数在其它的源文件中定义,没有在引用的源文件中声明,那编译器只知道要调这样一个函数,既不知道该给它传什么参数(传任务参数编译器都会认为是合法的),也不知道该返回什么值,x86_64上编译器把整形或地址返回值放在eax/rax中,浮点型放入xmm0中,单从返回值上来看,编译器默认是把这个陌生函数的返回值定为整形,由于在外层期望的是个浮点型,编译器在调用完func后就把整形的返回值再转换成浮点型放入xmm0中,也就导致了上述的问题。

   返回值是一方面,函数参数会带来更难调试的问题,x86_64在参数较少时使用寄存器传参,ia32使用栈传参,这时候如果外部函数未声明,那你传错误的参数也是能编译通过的,但最后的结果就是各种诡异了,往往会带来一些复杂难调的问题,但其实对于gcc来说,打开-Wimplicit-function-declaration选项的话这些未声明的问题都是会有warning提示的:

   warning: implicit declaration of function ‘func’

   所以好的编程习惯是打开-Wall,消除所有的warning。

建议继续学习:

  1. C语言中史上最愚蠢的Bug    (阅读:7095)
  2. C的那些事儿    (阅读:5413)
  3. C 语言的前世今生    (阅读:5155)
  4. C语言结构体里的成员数组和指针    (阅读:4973)
  5. C语言的那些个关键字们    (阅读:4539)
  6. C#和C++混合编程的一些tips    (阅读:3311)
  7. 周末闲谈:C and C++, why use c++?    (阅读:3274)
  8. C++11 中值得关注的几大变化(详解)    (阅读:2588)
  9. Effective C++ 3rd 的一点评论    (阅读:2315)
  10. Javascript中的函数声明和函数表达式    (阅读:2098)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1