碰到一个诡异的问题

千树之影 2015-05-21 11:18:32
加精
今天碰到一个bug,百般排查之后发现是exp函数的结果不对。检查后原因是没有包含<math.h>,包含后结果就正确了。
但问题在于,没有包含math.h的情况下,为什么编译能通过呢?而且没找到项目中有任何名为exp的函数或宏定义!

为了验证这个问题,我又新建了一个.c文件,
int test()
{
float a=exp(0);
float b=exp(1);
return 0;
}
没有包含任何头文件,编译竟然能过!然后a,b的值都是错的。

有人知道这是什么问题吗?
编译环境是vs2008.
...全文
2738 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
ainihot7 2016-05-10
  • 打赏
  • 举报
回复
原因很简单,没有包含math.h, 就没有exp函数的原型,所以参数传递和返回值都是错误的
艺哥来了 2016-05-09
  • 打赏
  • 举报
回复
说得,非常好啊
ArthurJava 2016-04-30
  • 打赏
  • 举报
回复
调用的每个库函数都有确定性的包含头文件的,c/c++的编译器有不少重写的库函数
slmax1 2016-04-30
  • 打赏
  • 举报
回复
这是低安全性!!!!!
毕健 2016-04-30
  • 打赏
  • 举报
回复
encoderlee 2016-04-28
  • 打赏
  • 举报
回复
在C++中没有包含头文件,是无法编译通过的 但在C语言中没有包含头文件,也是可以编译通过的 C语言中有个东西叫"隐式函数声明" 你可以在a.c中写一个函数 然后在b.c中调用它,也是能编译通过的 出错的原因楼上几位已经说到了
会飞_龙鱼 2016-04-28
  • 打赏
  • 举报
回复
头文件没有,不能调用
赵4老师 2016-04-28
  • 打赏
  • 举报
回复
理解讨论之前请先学会如何观察! 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程! 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步Debug版对应汇编一行! 单步Debug版对应汇编千行不如单步Release版对应汇编一行! 不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他!) VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
qq_34823835 2016-04-28
  • 打赏
  • 举报
回复
用其它编译器
xuzuning 2016-04-28
  • 打赏
  • 举报
回复
生来就是这样!TC2 也是如此 这个要追溯 C 的老祖宗的责任了
qq_16457811 2016-04-28
  • 打赏
  • 举报
回复
原因很简单,没有包含math.h, 就没有exp函数的原型,所以参数传递和返回值都是错误的
qq_16457811 2016-04-28
  • 打赏
  • 举报
回复
原因很简单,没有包含math.h, 就没有exp函数的原型,所以参数传递和返回值都是错误的
杰_杰 2016-04-28
  • 打赏
  • 举报
回复
原因很简单,没有包含math.h, 就没有exp函数的原型,所以参数传递和返回值都是错误的
杰_杰 2016-04-28
  • 打赏
  • 举报
回复
原因很简单,没有包含math.h, 就没有exp函数的原型,所以参数传递和返回值都是错误的
fefe82 2016-04-28
  • 打赏
  • 举报
回复
引用 13 楼 lm_whales 的回复:
微软编译器好像没有隐式声明这回事吧 试试看 老式编译器是有要求的 更古老的编译器,只是对函数参数比较随意点 这个内建函数,应该是半新不旧的标准 MS 应该还没来得及实现吧 老式的C 除了scanf,printf 之外,都要求函数有声明或者定义 scanf,printf 是唯一可以直接使用的两个函数 不过后来,也有编译器(几乎所有)都要求必须 声明 也就是 #include <stdio.h> gcc linux 都是比较新的软件,虽然比较流行,跟那些古老的编译器和操作系统比起来,还是年轻得多
C (不是C++) 最新的标准都不要求函数使用前一定要声明。 直接使用默认声明是 int func(); ===== 注意 C 里,int func(); 跟 int func(void); 不是一码事,前者对参数没有任何要求,后者不能有任何参数。
xujunxiang96 2016-04-28
  • 打赏
  • 举报
回复
原因很简单,没有包含math.h, 就没有exp函数的原型,所以参数传递和返回值都是错误的
列子汤问 2016-04-27
  • 打赏
  • 举报
回复
嗯,编译器怎么处理的问题。
lm_whales 2016-04-26
  • 打赏
  • 举报
回复
微软编译器好像没有隐式声明这回事吧 试试看 老式编译器是有要求的 更古老的编译器,只是对函数参数比较随意点 这个内建函数,应该是半新不旧的标准 MS 应该还没来得及实现吧 老式的C 除了scanf,printf 之外,都要求函数有声明或者定义 scanf,printf 是唯一可以直接使用的两个函数 不过后来,也有编译器(几乎所有)都要求必须 声明 也就是 #include <stdio.h> gcc linux 都是比较新的软件,虽然比较流行,跟那些古老的编译器和操作系统比起来,还是年轻得多
fefe82 2016-04-26
  • 打赏
  • 举报
回复
C 语言没有对函数声明的要求,也就是不需要函数在使用前先对函数进行声明 没有声明的函数默认返回 int 。 对函数的使用与实际函数的定义不一致时,结果是不确定的。
qq_24753517 2016-04-26
  • 打赏
  • 举报
回复
你好,请问你是做机器视觉开发工作的人员吗?
加载更多回复(10)

69,336

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧