为什么C语言需要函数声明
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。
建议继续学习:
- C语言中史上最愚蠢的Bug (阅读:7079)
- C的那些事儿 (阅读:5391)
- C 语言的前世今生 (阅读:5092)
- C语言结构体里的成员数组和指针 (阅读:4848)
- C语言的那些个关键字们 (阅读:4523)
- C#和C++混合编程的一些tips (阅读:3291)
- 周末闲谈:C and C++, why use c++? (阅读:3227)
- C++11 中值得关注的几大变化(详解) (阅读:2572)
- Effective C++ 3rd 的一点评论 (阅读:2259)
- Javascript中的函数声明和函数表达式 (阅读:2091)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:levin 来源: basic coder
- 标签: C 函数声明
- 发布时间:2013-08-14 13:46:25
- [56] Oracle MTS模式下 进程地址与会话信
- [56] IOS安全–浅谈关于IOS加固的几种方法
- [55] 如何拿下简短的域名
- [54] 图书馆的世界纪录
- [53] Go Reflect 性能
- [53] android 开发入门
- [50] 【社会化设计】自我(self)部分――欢迎区
- [50] 读书笔记-壹百度:百度十年千倍的29条法则
- [39] 程序员技术练级攻略
- [33] 视觉调整-设计师 vs. 逻辑