【发布时间】:2017-07-17 17:01:21
【问题描述】:
我有一个函数返回一个unsigned long,它实际上是一个float。
我们将调用该函数unsigned long foo()
当我像这样调用 printf 时:
printf("%f", foo());
它总是会打印出0.00000
但是当我这样投射时:
unsigned long bar = foo();
printf("%f", *((float *)(&bar)));
它正确输出浮点数。
使用"%x" 打印我可以看到二进制表示不同。令人惊讶的是,unsigned long 版本看起来更像是一个实际的浮点表示(41ba019a vs 40000000)
我在我的系统上仔细检查了unsigned long 和float 的大小是否相同。
所以我的问题是:
这样转换指针如何改变所指向的值?
编辑: foo() 的相关部分本质上是
unsigned long foo()
{
float a = 22.4;
return *(unsigned long *)(&a) ;
}
【问题讨论】:
-
你没有向我们展示最重要的事情。让我们看看
foo()。 -
unsigned long 的值是从浮点开始转换的。该函数可以根据参数返回不同的类型。
-
所以?让我们看看相关的部分。
-
这不是因为float在传递给函数时首先被提升为double,所以printf期望将double打印为float吗?由于 foo 不返回浮点数,因此不执行转换,因此为 0.0000。
-
这是一个非常糟糕的代码。如果您希望该函数返回不同的类型,请使其与所有可能类型的
union一起使用并返回它。不要这样重新解释。这将有助于避免此类问题和其他潜在的 UB。