我在测试中遇到了这个问题,我仍然不明白给出的答案:
假设我写了以下代码:
#include <math.h>
#include <stdio.h>
float cos(float x){
return 1-x*x/4;
}
int main()
{
printf("%0f",cos(0.05f)+sin(0.05f));
}
我们假设cos
和sin
在数学库中声明和定义(接收并返回double
),并且我正在尝试将我的代码与数学库链接。
另一个假设是cos
中定义了math.c
。
问题是:
“代码编译/链接是否成功?如果是,那么 cos 函数 会被叫到吗?“
答案是:
“是的,代码将编译,我的 cos 将被调用”。
如何解释这种行为?这些函数不是多个定义吗?
答案 0 :(得分:7)
您的老师可能犯了错误并打算使用double cos(double x)
。在这种情况下,许多C实现将接受该程序,它将链接并运行,因为链接器从其提供的对象模块中获取每个模块,但仅采用需要它提供的库中的模块。因此,因为cos
已经在程序中定义,所以链接器不会从数学库中获取它。但是,虽然这适用于许多C实现,但它违反了标准C的规则,后者保留了库标识符;普通程序可能无法定义它们。
另一种可能性是您的老师不打算包含math.h
。这将使cos
的声明不是错误,因为它不会与另一个声明冲突,但这意味着程序也应声明sin
,因为它已被使用。 / p>
答案 1 :(得分:2)
根本不起作用。
你会看到类似这样的错误:
conflicting types for 'cos'
我用gcc编译器的代码块得到它...
您可以使用其他解决方案,请查看此帖:Override a function call in C
答案 2 :(得分:2)
它不会编译。
我在return 0;
末尾添加了main()
,以解除-Wall -Werror
的第二个问题。如果你这样做,你会看到:
$ gcc -Wall -Werror costest1.c -o costest -lm
costest1.c:5:1: error: conflicting types for ‘cos’
这在编译阶段失败,因为math.h
还定义了一个名为cos
的函数。请注意cos
的原型是:
double cos(double x);
不
float cos(float x);
如果你没有包含math.h
,你就可以编译,但会得到:
$ gcc -Wall -Werror costest1.c -o costest -lm
costest1.c:5:1: error: conflicting types for built-in function ‘cos’ [-Werror]
costest1.c: In function ‘main’:
costest1.c:13:3: error: implicit declaration of function ‘sin’ [-Werror=implicit-function-declaration]
costest1.c:13:32: error: incompatible implicit declaration of built-in function ‘sin’ [-Werror]
cc1: all warnings being treated as errors
这是因为cos
不是正常功能,而是作为builtin
处理。如您所见,它是根据sin
定义的。如果cos
是正常函数,您会看到某种重复的符号错误。
在C中,即使它们具有不同的参数,也不能有两个具有相同名称的函数。在C ++中,您可以通过调用参数(但不仅仅是返回类型)来区分相同名称的方法。
答案 3 :(得分:2)
修改强>
我认为问题是关于C ++而不是C,因为编译代码作为C程序会产生冲突类型错误:https://eval.in/93380。
此行为是由Function Overloading引起的。 cos()
函数具有程序集名称_cos@double
,并且重新声明cos()
函数接受float
参数将具有程序集名称_cos@float
并且它不会冲突使用数学库中定义的cos()
。使用cos()
参数调用float
将转换为对您自己_cos@float
的汇编函数cos()
的调用。
请注意,只有C ++而不是C才允许Function Overloading。
在C中,您只能在不更改函数的参数和返回类型(https://eval.in/93381)的情况下执行此操作,否则将生成先前的错误。
正如假设澄清(cos在math.c中定义),案例中的cos()
函数不是math.h
中定义的函数,在这种情况下答案是真的,如果它被定义为接受类型float
的参数并返回类型float
的值。在这种情况下,程序将编译没有任何问题。
答案 4 :(得分:2)
6.7声明
...
约束
...
4同一范围内涉及同一对象或功能的所有声明均应注明 兼容类型
您发布的代码违反了上述约束条件; math.h
将cos
声明为
double cos(double x);
此行为无法解释为为C ;它可以解释为C ++,它允许名称重载。
确保你真的在谈论C而不是C ++,否则你最终会感到非常困惑。
答案 5 :(得分:0)
不,它不能编译。
标头文件math.h
声明double cos(double)
。 C中不允许尝试过载。
error C2371: 'cos' : redefinition; different basic types