Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Cast to a struct?

Reply
Thread Tools

Cast to a struct?

 
 
Jack
Guest
Posts: n/a
 
      07-06-2006
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? If not, is there way in C++ to do it?

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;
}
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      07-06-2006
Jack wrote:
> 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? If not, is there way in C++ to do it?
>

Shouldn't that be C?

If you want to overlay types of the same size, use a union.

--
Ian Collins.
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      07-06-2006
Jack <(E-Mail Removed)> writes:
> 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".

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
MQ
Guest
Posts: n/a
 
      07-06-2006

I
>
> If you want to overlay types of the same size, use a union.
>


Wouldn't that depend upon the implementation of the compiler/platform,
in terms of how it represents the data type. It sounds like the OP
wants to do something like:

struct C
{
short hiword;
short loword;
};
union A
{
int b
struct C c;
};

would this not possibly behave differently depending on whether it was
compiled on a little-endain or big-endian machine?

 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      07-06-2006
MQ wrote:
> I
>> If you want to overlay types of the same size, use a union.

>
> Wouldn't that depend upon the implementation of the compiler/platform,
> in terms of how it represents the data type. It sounds like the OP
> wants to do something like:
>
> struct C
> {
> short hiword;
> short loword;
> };
> union A
> {
> int b
> struct C c;
> };
>
> would this not possibly behave differently depending on whether it was
> compiled on a little-endain or big-endian machine?


Yes, you are correct. Even worse, the compiler might insert padding
between hiword and loword so even on a system where short is half the
size of int the struct could be longer than an int.

Depending on what the OP actually wants to achieve, either using a
pointer to unsigned char pointing at the int or using shifting and
masking would be better. With the shifting/masking you are best working
with unsigned int otherwise you can get unexpected results.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
 
Reply With Quote
 
Herbert Rosenau
Guest
Posts: n/a
 
      07-06-2006
On Thu, 6 Jul 2006 02:01:19 UTC, Jack <(E-Mail Removed)> wrote:

> Is it possible to cast a 4-byte data type (e.g. an unsigned int) to a
> 4-byte struct?


No.

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? If not, is there way in C++ to do it?


You are leaving the lands of standard C. What you tries is higly
implementation specific and has nothing to do with standard C. Find a
group that is related to your implementation and ask there for a way
to get it - if it is possible.

At least you gets an application that is in no way compatible - maybe
not even between 2 different versions of the compiler you are using.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
Reply With Quote
 
SM Ryan
Guest
Posts: n/a
 
      07-06-2006
Jack <(E-Mail Removed)> wrote:
# 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? If not, is there way in C++ to do it?
#
# 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;
# }

You can use memcpy
assert(sizeof n==sizeof(mystruct_t));
mystruct_t N;
memcpy(&N,&n,sizeof n);
return N;

# int main()
# {
# mystruct_t s = test();
# return 0;
# }
#
#

--
SM Ryan http://www.rawbw.com/~wyrmwif/
I think that's kinda of personal; I don't think I should answer that.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is the result of valid dynamic cast always equal to the result ofcorrespondent static cast? Pavel C++ 7 09-18-2010 11:35 PM
error C2440: 'return' : cannot convert from 'const char *' to 'const unsigned short *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast Abhijit Bhadra C++ 2 12-01-2004 04:43 PM
malloc - to cast or not to cast, that is the question... EvilRix C Programming 8 02-14-2004 12:08 PM
to cast or not to cast malloc ? MSG C Programming 38 02-10-2004 03:13 PM
how to cast system.intptr to struct BestNews ASP .Net 1 09-03-2003 09:04 AM



Advertisments