c中具有相同功能的两个声明

时间:2014-01-22 14:31:52

标签: c

我在测试中遇到了这个问题,我仍然不明白给出的答案:

假设我写了以下代码:

#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));
}

我们假设cossin在数学库中声明和定义(接收并返回double),并且我正在尝试将我的代码与数学库链接。

另一个假设是cos中定义了math.c

问题是:

  

“代码编译/链接是否成功?如果是,那么 cos 函数   会被叫到吗?“

答案是:

  

“是的,代码将编译,我的 cos 将被调用”。

如何解释这种行为?这些函数不是多个定义吗?

6 个答案:

答案 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)

Online C2011 standard

6.7声明
...
约束
...
4同一范围内涉及同一对象或功能的所有声明均应注明 兼容类型

您发布的代码违反了上述约束条件; math.hcos声明为

double cos(double x);    

此行为无法解释为为C ;它可以解释为C ++,它允许名称重载。

确保你真的在谈论C而不是C ++,否则你最终会感到非常困惑。

答案 5 :(得分:0)

不,它不能编译。

标头文件math.h声明double cos(double)。 C中不允许尝试过载。

error C2371: 'cos' : redefinition; different basic types