繁体   English   中英

函数返回错误值,在C中,使用gcc英特尔编译器

[英]Function returning wrong value, in C, using gcc Intel compiler

我写这篇是因为我真的不知道为什么会这样。 我知道如何纠正它/绕过它,但我想知道的是这种情况发生的原因。 我正在使用C,我的编译器是在Intel机器上运行的gcc 4.4.1(TDM)。

有关浮点数的假设: - 符合IEEE 754标准 - 以Big Endian方式存储

假设我们有一个函数接受一个4字节的数组并将它们作为一个浮点数返回。 这是该功能的目标。 我们还要说,例如,所有函数都会以“正确的顺序”获取字节,因为系统是小端,它只是交换它们并将它们放入浮点数以返回一个值。 为简单起见,我不包括对NaN或INF的任何检查,因为这不是这个问题的目的。

float testFunction(char* arr)
{
    //this will be the float we return
    float ret;

    //let's just get a char pointer to the float so we can alter its byte values
    char* c = (char*)&ret;
    //just swap them so they conform with little endian byte order
    c[0] = arr[3];
    c[1] = arr[2];
    c[2] = arr[1];
    c[3] = arr[0];

    //up to here if you debug and watch ret's value it is correct as it is supposed to be
    return ret;
}

问题是无论我在哪里使用这个功能......让我们说如下

   float f = testFunction(arr);

然后浮点数f与作为参数传递的字节具有完全不相关的浮点值。

成功解决这个问题的方法是声明一个接受float作为参数的函数,并在函数内部给它一个值,如下所示:

void testFunction(char* arr,float* f)
{
   char* c = ((char*)f)
   c[0] = arr[3];
   c[1] = arr[2];
   c[2] = arr[1];
   c[3] = arr[0];
 }

但我的问题仍然是,为什么当我尝试返回值时会发生这种情况? 我确实理解float ret是函数范围内的临时值,但return语句应该将其值复制到函数之外。 不正确吗? 我错过了什么? 我想这一定是非常明显的事情。

实际上,在这两种情况下,浮点数应该具有“完全不相关”的值,除非您仔细地制作该数组的字符(例如float memcpy )。

您不能只设置字节并希望它与您平台上的表示形成神奇匹配。

摇摆。 由于类型转换,编译器无法识别f变量已更新。 对于编译器, f变量和c指针之间没有链接。 它不知道它是别名。 在ABI中,浮点数在寄存器中返回,它应该在return时从堆栈生成一个负载,但是当它看到f被单元化时,它什么也不做,并返回用于该寄存器的随机内容。 如果将float声明为volatile它应该按照您的预期执行。

如上所述,这是一个疯狂的猜测。

我会说一些愚蠢的话。 但是尝试初始化ret ,就像float ret = 0;

我不确定你是否可以一次初始化一个变量“piecemail”一个char ,并认为它是为C标准(和编译器)“初始化”的

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM