Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning float in void* function

I'm learning how pointers works, but I don't understand one thing in this code. Returning int in void* function works like a charm, but returning float does'nt.

#include <stdio.h>

void* square (const void* num);

int main() {
  int x, sq_int;
  x = 6;
  sq_int = square(&x);
  printf("%d squared is %d\n", x, sq_int);

  return 0;
}

void* square (const void *num) {
  int result;
  result = (*(int *)num) * (*(int *)num);
  return result;
}
#include <stdio.h>

void* square (const void* num);

int main() {
  float x, sq_int;
  x = 6;
  sq_int = square(&x);
  printf("%f squared is %f\n", x, sq_int);

  return 0;
}

void* square (const void *num) {
  float result;
  result = (*(float *)num) * (*(float *)num);
  return result;
}
like image 508
gunhasiz Avatar asked Dec 23 '22 23:12

gunhasiz


1 Answers

Both of your functions invoke undefined behaviour, as the return type and type of the expression in the return statement do not match.

As on why it seem to work, read about undefined behaviour.

That said, turn up the compiler warnings where you treat all warnings as error, and with that setting this code should not even compile to produce a binary, as it contains a constraint violation which is supposed to produce a diagnostic (warning).

Related notes:

Quoting from C11, chapter §6.8.6.4

[...] If the expression has a type different from the return type of the function in which it appears, the value is converted as if by assignment to an object having the return type of the function.

and regarding simple assignment, from chapter §6.5.16.1, simple assignment:

Constraints

One of the following shall hold:

  • the left operand has atomic, qualified, or unqualified arithmetic type, and the right has arithmetic type;
  • the left operand has an atomic, qualified, or unqualified version of a structure or union type compatible with the type of the right;
  • the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
  • the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) one operand is a pointer to an object type, and the other is a pointer to a qualified or unqualified version of void, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
  • the left operand is an atomic, qualified, or unqualified pointer, and the right is a null pointer constant; or
  • the left operand has type atomic, qualified, or unqualified _Bool, and the right is a pointer.

So, you cannot legally assign an int or float to a pointer type - this is a constraint violation.

like image 160
Sourav Ghosh Avatar answered Dec 31 '22 01:12

Sourav Ghosh