torri said:
Ok. First, my aim is to make a library compiling with suncc. That library
is designed to interpret limited Small programs (Small is a language).
Think of it as a compiler for Small programs. Note that I didn't write
that library. I just try to compile on OpenSolaris.
The part where there is that problem is about conversion from a C float
to a Small "cell" (actually an int).
Here are the used types:
typedef int Embryo_Cell;
typedef union
{
float f;
Embryo_Cell c;
} Embryo_Float_Cell;
/** Float to Embryo_Cell */
#define EMBRYO_FLOAT_TO_CELL(f) ((Embryo_Float_Cell) f).c
The only time you can do anything like that is when the floating point
object that you're referring to is in fact a member of such a
structure, and even then, only if it was NOT the member most recently
filled:
Embryo_Float_Cell cell;
cell.c = 12345;
In that case, the following construct will work:
Embryo_Cell cc = (* (Embryo_Float_Cell*)&cell.f).c
Now cc will contain 12345.
However, given your examples below, it's clear that this macro is
intended to be used in contexts where the coditions described above
don't apply. It's simply intended to perform type punning, and as such
cannot be made portable. Among other things, it appears to be based
upon the assumption that sizeof(int) == sizeof(float). I'd recommend
checking that assumption with an assert() statement at least once,
somewhere early in your program.
Assuming that those types have the same size and alignment, there's no
need to declare the union. The desired conversion can be performed
simply as
float f = 123.456;
Embryo_Cell c = *(Embryo_Cell*)&f;
This approach is exactly as unsafe as the original code; if the
original code doesn't make your programs seriously malfunction, the
same will probably be true of this simpler approach, too.
A safer approach would use memcpy():
memcpy(&c, &f, sizeof c);
This is safer only in the sense that it doesn't have undefined
behavior. That doesn't help much, because ''c' isn't guaranteed to
contain a valid representation of an 'int'. If it contains a trap
representation, the behavior of your program becomes undefined as soon
as your program tries to use the value of C.