Jack said:
Is it possible to cast a 4-byte data type (e.g. an unsigned int) to a
4-byte struct? Sometimes the HIWORD and LOWORD of a 4-byte value
contain information independent of each other. Is there a direct way
to perform this cast?
No. Neither the source expression nor the target type of a cast is
allowed to be a struct (except that any expression can be cast to
void).
If not, is there way in C++ to do it?
How would we know that?
For example, I would like my function test() to work the way it is
coded below. It produces a compiler error though:
#include <pshpack2.h> // 16-bit padding
// My 4-byte struct
typedef struct _mystruct_t
{
unsigned short cx;
unsigned short cy;
} mystruct_t;
#include <poppack.h>
mystruct_t test()
{
unsigned int n = 0xffff0001;
return (mystruct_t)n;
}
int main()
{
mystruct_t s = test();
return 0;
}
I think you've misunderstood what a cast is for.
A cast specifies a type conversion. A conversion takes the *value* of
a source expression, and yields a value of another type (or the same
type); the result has some close relationship to the original value
(for example, it may be the same value in the case of a numeric
conversion). A conversion operates on values, not representations; it
doesn't just reinterpret the bits of the representation of the source.
For example, the cast expression (double)42 yields the value 42.0; the
int value 42 and the double value 42.0 have the same mathematical
value, but completely different representations.
(Pointer conversions typically work by reinterpreting bits, but only
because that makes sense in terms of the values.)
Looking at your code:
Avoid identifiers starting with '_'. Some of them are reserved to the
implementation in some or all contexts. It's much easier to avoid
such identifiers altogether than to remember the special cases in
which you can get away with using them.
Personally, I wouldn't use a typedef at all; I'd just declare the type
as "struct mystruct_t", and refer to it as "struct mystruct_t". But
if you prefer to use the typedef, it perfectly legal.
You're assuming, I think, that unsigned short is exactly 16 bits, and
unsigned int is exactly 32 bits. If the code isn't intended to be
portable, that may be acceptable; otherwise your code is likely to
break on systems where that isn't the case. (You also can't portably
assume that unsigned int is exactly twice as big as unsigned short;
I've worked on systems where it's the same size, and on others where
it's four times as big.)
What is the conversion supposd to do? I'm guessing you want to store
0xffff in one of the members and 0x0001 in the other, but which is
which? If you copy the value directly (using memcpy, or a union, or
pointer tricks), the results will vary depending on whether your
platform is big-endian or little-endian. You'll need to decide
exactly what you want to do before you can figure out the best way to
do it.
Finally, <pshpack2.h> and <poppack.h> are non-standard headers, and I
don't know what you mean by "16-bit padding".