在 Microsoft Visual Studio 2019 上观察到。 不确定其他版本是否同样受到影响。
考虑这段代码:
#include <stdio.h>
int main()
{
const double frac = -1.0;
printf("%f\n", (double)exp(frac));
}
无论如何,这段代码不应该编译。或者有人会这么认为。它缺少 math.h 标头。 它肯定无法在 gcc 上编译。 然而,在 Microsoft Visual C++ 2019 上似乎确实如此。 但是,这个神秘版本的
exp()
返回了意想不到的结果。
exp(-1.0)
exp(-0.61)
#include <math.h>
,就像我一开始就应该做的那样。
所以我的问题是:当代码省略包含 math.h 时,Microsoft 编译器会找到exp()
的什么定义?
注: 这里可能提供的线索是这个神秘的定义似乎返回一个整数。上面代码片段中的转换看起来是多余的,但删除它会发现printf()
得到了一个它需要浮点的整数。
exp()
函数仍然存在于库中,并将被链接到。
但是,由于头文件中没有 exp()
的定义,它将默认采用
int
参数并返回 int
值。这不是库函数接受或返回的内容,也是您得到奇怪结果的原因。如果您在包含后添加 double exp(double);
,它将按您的预期工作。您应该收到有关未定义函数的警告。不要忽视那些! (或者不要将它们关闭。)那里的警告是有原因的。原来是这个原因。