为什么此函数返回0而不是double? [英] Why this function returns 0 instead of a double?

查看:69
本文介绍了为什么此函数返回0而不是double?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在测试代码,但我不明白为什么它会显示较高的值为0".这是主要功能:

I was testing a code and I don't understand why it prints "The higher value is 0". This is the main function:

int main() {
    double a,b,c;
    a=576;
    b=955;
    c=higher(a,b);
    printf("The higher value is %g\n", c);
    return 0;
}

在另一个.c文件中,我具有以下功能:

and in another .c I have this function:

double higher(double a, double b){
    if (a>b)
        return a;
    return b;
}

注意:如果我在main.c中放置了high(),它可以正常工作,但是这样可以告诉我更高的值是0.如果我将higer()的返回值像这样进行转换,它也可以工作:

NOTE: if I put higher() in main.c it works correctly, but in that way it tells me the higher value is 0. It also works if I cast the return in higer() like this:

return (int)b;

如果返回双精度值的函数与main()处于相同的.c或位于不同的函数中,是否存在差异?

Is there a difference if a function that returns a double is in the same .c as main() or in a different one?

推荐答案

使用C99或C11编译器进行编译并阅读警告.您正在使用没有原型的函数.

Compile with a C99 or C11 compiler and read the warnings. You are using the function without prototype.

在没有原型的情况下,C99之前的版本假定有一个默认情况下返回 int 的函数.C99及更高版本,需要原型.

Without a prototype, pre-C99 assumes a function to return int by default. C99 and later, require a prototype.

即使未启用其他警告:

$ cat test.c
int main()
{
    int i = f();
    return 0;
}

int f(void)
{
   return 1;
}

$ gcc -std=c11 test.c
test.c: In function ‘main’:
test.c:13:2: warning: implicit declaration of function ‘f’ [-Wimplicit-function-declaration]
  int i = f();

请注意,如果编译 -std = c90 ,gcc不会发出警告,但如果启用警告 -Wall ,则会发出警告.

Note that gcc will not warn if compiling -std=c90, but will if enabling warnings -Wall.

因此,由于预期 higher()返回一个 int ,该值将通过赋值转换为 double (类型为 c 不变).

So, as higher() is expected to return an int, the value is converted to double by the assignment (the type of c is not changed).

现在有趣的部分是: 未定义的行为 (UB,请记住该短语!),因为调用和函数实现的签名不同.

And now for the funny part: undefined behaviour (UB, memorize this phrase!) due to different signature for call and implementation of the function.

发生什么可能是根据过程调用标准(PCS)和应用程序二进制接口(ABI)-检查维基百科.简要地说: high 本身返回一个 double .这很可能通过浮点CPU寄存器传递给调用方.调用者OTOH期望返回值(由于缺少原型)在整数CPU寄存器中(碰巧会保留 0 ).

What might happen is according to procedure call standard (PCS) and the application binary interface (ABI) - check Wikipedia. Briefly: higher itself returns a double. That is likely passed in a floating point CPU register to the caller. The caller, OTOH, expects the return value (due to the missing prototype) in an integer CPU register (which happens to hold 0 by chance).

因此,由于他们显然沟通不畅,您得到了错误的结果.请注意,这只是一个推测,取决于PCS/ABI.要记住的是,这是UB,所以任何事情都可能发生,甚至恶魔飞出你的鼻子.

So, as they apparently have misscommunication, you get the wrong result. Note that this is a bit speculatively and depends on the PCS/ABI. All to remember is this is UB, so anything can happen, even demons flying out of your nose.

为什么使用原型:

好吧,您已经注意到,如果您正确调用函数,编译器也不知道.更糟糕的是,它不知道使用了哪种参数类型以及返回了哪种结果类型.这特别是一个问题,因为C会自动转换某些类型(您在这里确实遇到过).

Well, you allready noticed, the compiler has no idea, if you call a function correctly. Even worse, it does not know, which argument types are used and which result type is returned. This is particlularily a problem, as C automatically converts some types (which you did encounter here).

由于经典的K& R(预标准)C没有原型,因此将未知函数的所有自变量假定为调用中的标量自变量 int / double .结果默认为 int .(很久以前,我可能会丢失一些部分;我从K& R开始进行一些编码,弄乱了类型(正是您在这里遇到的问题,但没有一个干净的解决方案),等等,然后将其扔到角落,并在Modula中愉快地进行了编程-2,直到几年后我尝试使用ANSI-C.

As classical K&R (pre-standard) C did not have prototypes, all arguments to unknown functions were assumed int/double for scalar arguments on a call. The result defaults to int. (Long time ago, I might be missing some parts; I started some coding with K&R, messed up types (exactly your problem here, but without a clean solution), etc., threw it in a corner and happily programmed in Modula-2 until some years later I tried ANSI-C).

如果现在正在编译代码,则应该至少符合(并编译)C99,更好地使用当前标准(C11).

If compiling code now, you should at least conform to (and compile for) C99, better use the current standard (C11).

这篇关于为什么此函数返回0而不是double?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆