Note: This question attempts to improve what I attempted to ask here, but fell short.
Also, I have seen this, and this. They discuss similar concepts, but do not answer these questions.
My environment is Windows 10, and for testing I used two compilers, CLANG and GCC.
I am passing variables via a void *
function argument, and need to convert them. I would like to get some feedback on inconsistencies I am seeing between methods for different types.
The following is a stripped-down depiction of a test function that accommodates multiple input types using a void *
parameter, and an enumerated value parameter to indicate the type being passed in.:
void func(void *a, int type)
{
switch(type) {
case CHAR://char
char cVar1 = (char)a; //compiles with no warnings/errors, seems to work
char cVar2 = *(char *)a; //compiles with no warnings/errors, seems to work
break;
case INT://int
int iVar1 = (int)a; //compiles with no warnings/errors, seems to work
int iVar2 = *(int *)a; //compiles with no warnings/errors, seems to work
break;
case FLT://float
float fVar1 = (float)a; //compile error: (a1)(b1)
float fVar2 = *(float *)a; //requires this method
case DBL://double
double dVar1 = (double)a; //compile error: (a1)(b1)(b2)
double dVar2 = *(double *)a;//this appears to be correct approach
break;
};
}
Calling method:
int main(void)
{
char c = 'P';
int d = 1024;
float e = 14.5;
double f = 0.0000012341;
double g = 0.0001234567;
void *pG = &g;
func(&c, CHAR);//CHAR defined in enumeration, typical
func(&d, INT);
func(&e, FLT);
func(&f, DBL);
func(pG, DBL);
return 0;
}
Exact error text relating to flags in comments above follows:
CLANG - version 3.3
- (a1) - ...error: pointer cannot be cast to type 'float'
gcc - (tdm-1) 5.1.0
- (b1) - ...error: pointer value used where a floating point value was expected
- (b2) - ...error: pointer cannot be cast to type 'double'
For reference in discussion below
- method 1 ==
type var = (type)val;
- method 2 ==
type var = *(type *)val;
My results indicate that converting float
& double
require method 2.
But for char
& int
method 2 seems to be optional, i.e. method 1 compiles fine, and seems to work consistently.
questions:
It would seem that recovering a value from a
void *
function argument should always require method 2, so why does method 1 (seem to) work withchar
andint
types? Is this undefined behavior?If method 1 works for
char
andint
, why does it not also work with at least thefloat
type? It's not because their sizes are different, i.e.:sizeof(float) == sizeof(int) == sizeof(int *) == sizeof(float *)
. Is it because of a strict aliasing violation?