First of all, it is illegal in c to implicitly cast integer to pointer.
return (*(int * )num) * (*(int *)num);
Your compiler should give at least a warning on this. If your compiler does not give you any warning, i think there must be some compiler flags to make it warn you.
However, many C compilers don't just stop compiling when they meet those kind of things. They warn you and just compile it as you wrote like this:
return (void *)(((int * )num) * (*(int *)num));
You expected that square()
must return void pointer to the result of the calculation, but casting an integer to void pointer does not mean you get pointer to that integer. It means your compiler will interpret your bit arrays of that integer as void pointer. If that integer is 9, the resulting void pointer will point to address 9.
This is not illegal, but this has undefined behavior when you actually try to access where the void pointer points to. Undefined behavior means that you can get different result when you compile it on other compilers.
Also, printf("%d", square(ptr))
cause undefined behavior because you specified you will give int
to your second parameter but you didn't. This also can result to anything depends on your compiler and computer, but in this case, your compiler just interpreted your bit array of that void pointer as integer.
If you want to return void pointer that points to the result, you should do like this:
void *square(const void *num)
{
int *ret;
ret = malloc(sizeof(int));
*ret = (*(int *)num) * (*(int *)num);
return ret;
}
If you want to know more about what is undefined behavior, you can find c standard documents from here. It is not a good practice to rely on what your compiler do when you want to know how would some code snippet works.