在void *函数中返回float

时间:2019-05-24 10:31:09

标签: c function pointers return

我正在学习指针的工作方式,但是我不理解此代码中的一件事。 在void *函数中返回int就像一个超级按钮一样,但返回float却没有。

ndarray
[xval, yval, ...]

3 个答案:

答案 0 :(得分:6)

这两个函数都调用undefined behaviour,因为返回类型和return语句中表达式的类型不匹配。

关于似乎为什么起作用的信息,请阅读有关未定义行为的信息。

也就是说,在所有警告均视为错误的地方打开编译器警告,并设置该代码甚至不应编译为生成二进制文件,因为它包含约束违规,应该会产生诊断(警告)

相关说明:

引用C11,第6.8.6.4章

  

[...]如果表达式中有一个   type与出现的函数的返回类型不同,值为   就像分配给具有函数返回类型的对象一样进行转换。

以及关于简单分配的内容,请参见第6.5.16.1节简单分配

  

约束

     

应满足以下条件之一:

     
      
  • 左操作数具有原子,合格或不合格的算术类型,而右操作数具有算术类型;
  •   
  • 左操作数具有与右类型兼容的结构或联合类型的原子,合格或不合格版本;
  •   
  • 左操作数具有原子,限定或不限定的指针类型,并且(考虑到左操作数在左值之后将具有的类型   转换),两个操作数都是指向合格或不合格的指针   类型的兼容类型,并且左侧指向的类型具有   右侧所指类型的所有限定词;
  •   
  • 左操作数具有原子,限定或不限定的指针类型,并且(考虑到左操作数在左值之后将具有的类型   转换)一个操作数是一个指向对象类型的指针,另一个   是指向void的合格或不合格版本的指针,并且   左侧指向的类型具有指向该类型的所有限定符   靠右边
  •   
  • 左操作数是原子,限定或不限定的指针,右是空指针常量;或
  •   
  • 左边的操作数的类型是atomic,合格或不合格的_Bool,右边的是指针。
  •   

因此,您不能合法地将intfloat分配给指针类型-这是一个约束冲突。

答案 1 :(得分:2)

问题是您尝试将浮点数转换为指针。

C没有指定任何有关指针格式的内容。这是因为C试图抽象所有可能的体系结构,并且某些体系结构具有非常罕见的表示指针的方式。例如,在Lisp机器上,内存位置,因此指针以segment:offset表示。同样,在哈佛体系结构中,它将数据区域的代码区域和指针对这些不同区域的编码方式分开。 C仅在函数指针与对象指针之间进行区分,而对指针对象中每一位的含义一无所知。

在您的计算机上整数很好地转换的事实只是一个机会。如果您的计算机有64个总线地址,而32位是整数,则返回的指针具有一定意义,并且看起来与整数“相等”,这仅意味着体系结构可能具有与指针相同的整数值表示形式。

现在,在您的代码中,浮点数将转换为指针,而从指针转换回浮点数。浮点数的表示形式定义为正负号/指数/尾数,但指针的表示形式未定义,并且可能发生未定义的行为。

答案 2 :(得分:0)

如果您仍然希望此方法起作用,则应返回指向float的指针。但是,在函数中执行此操作会涉及一些堆分配。 代码可以像这样。我没有检查是否返回了真正的浮点数。这是你的任务

#include <stdio.h>
#include <stdlib.h>


void* square (const void* num);

int main() {
  float *x, sq_int;
  float value = 6;
  x = square(&value);
  printf("%f squared is %f\n", value, *x);
  free(x);
  return 0;
}

void* square (const void *num) {
  float *result = malloc(sizeof(float));
  *result = (*(float *)num) * (*(float *)num);
  return ((float*)result);
}