473,320 Members | 1,820 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Casting a structure to an int

I recently came across the following CAST macro which can cast anything
to any other thing:

#define CAST(new_type,old_object) (*((new_type *)&old_object))

union
{
char ch[4];
int i[2];
} my_union;

long longvar;

longvar = (long)my_union; Illegal cast
//////////////// ILLEGAL
longvar = CAST(long, my_union); Legal cast

I understands that why the CAST macro works but I cannot understands
that what is the problem in the following casting :

longvar = (long)my_union;

Can somebody please tell me that what is the problem in the above
casting mechanism?

PS This is not an assignment. I took this code from the following
link:
http://paul.rutgers.edu/~rhoads/Code/cast_anything.c

Feb 13 '06 #1
12 1918
Hello,

See inserted comments:

ca********@yahoo.com wrote:
I recently came across the following CAST macro which can cast anything
to any other thing:

#define CAST(new_type,old_object) (*((new_type *)&old_object))

union
{
char ch[4];
int i[2];
} my_union;

long longvar;

longvar = (long)my_union; Illegal cast
//////////////// ILLEGAL
Sizeof of my_union? and sizeof of long?
longvar = CAST(long, my_union); Legal cast

I understands that why the CAST macro works but I cannot understands
that what is the problem in the following casting :

longvar = (long)my_union;

Can somebody please tell me that what is the problem in the above
casting mechanism?

PS This is not an assignment. I took this code from the following
link:
http://paul.rutgers.edu/~rhoads/Code/cast_anything.c


"cast anything or the first bytes of anything or even all it and some
parts of who knows what". Practical, nice and dangerous.

Kind regards.

Feb 13 '06 #2
ca********@yahoo.com wrote:
I recently came across the following CAST macro which can cast anything
to any other thing:

#define CAST(new_type,old_object) (*((new_type *)&old_object))


A perfect example of what shouldn't be done.
Feb 13 '06 #3
ca********@yahoo.com writes:
I understands that why the CAST macro works but I cannot understands
that what is the problem in the following casting :

longvar = (long)my_union;


In a cast expression, the expression whose value is cast must
have a scalar type, but a union is not a scalar type. (A scalar
type is an arithmetic type or a pointer type.)
--
"I should killfile you where you stand, worthless human." --Kaz
Feb 13 '06 #4


ca********@yahoo.com wrote On 02/13/06 14:08,:
I recently came across the following CAST macro which can cast anything
to any other thing:

#define CAST(new_type,old_object) (*((new_type *)&old_object))


"Anything?"

CAST(void, stdin)

CAST(char*, printf)

CAST(double, 42)

... and I imagine other examples could be dreamed up.

But even for those cases where there's no compile-time
error, the whole idea is wrong-headed. All CAST attempts
to do is re-interpret the bits of one thing as if they had
some other type. There's no attempt to convert, no concern
for safety, and no reason to rely on whatever result you
might happen to get. It's a Bad Idea, almost always --
and you can delete the "almost" if you're trying to write
code that's even marginally portable.

--
Er*********@sun.com

Feb 13 '06 #5
ca********@yahoo.com wrote:
I recently came across the following CAST macro which can cast anything
to any other thing:

#define CAST(new_type,old_object) (*((new_type *)&old_object))

union
{
char ch[4];
int i[2];
} my_union;

long longvar;

longvar = (long)my_union; Illegal cast
//////////////// ILLEGAL
longvar = CAST(long, my_union); Legal cast

I understands that why the CAST macro works but I cannot understands
that what is the problem in the following casting :

longvar = (long)my_union;

Can somebody please tell me that what is the problem in the above
casting mechanism?

PS This is not an assignment. I took this code from the following
link:
http://paul.rutgers.edu/~rhoads/Code/cast_anything.c


First of all: This is not a safe technique.

long longvar = (long)my_union;
is just an explicit version of
long longvar = my_union;
because a cast is just an explicit conversion.

As there is no way to convert an arbitrary aggregate type
into an integer type, your compiler will complain.

So, what is the "trick" with the CAST macro?
You do not take the "value" of the aggregate but the
_representation_.
CAST(long, my_union);
tells the compiler to take the bit pattern at &my_union
and pretend that it is the bit pattern of a long.

When does this work guaranteedly?
Whenever the first argument of the CAST macro is
1) of type unsigned char or
2) if the second argument is of structure type, of
the type of the first member
3) if the second argument is of union type, of the
type of the member which has been last written to
4) if the second argument is of array type, of the
type of the array elements
5) a "recursive mixture" of 2)-4)

Example for 5)

struct { union { short foo[5]; float bar[3] } baz } qux;
short firstfoo;

qux.baz.foo[0] = 7;
firstfoo = CAST(short, qux);

There are other times when this works but this is a
implementation dependent thing.

When will it break?
Imagine your example for
sizeof (long) == 8
sizeof (int) == 2 or sizeof (int) == 4
and alignment requirement "long address can be divided
by 8 without remainder, int address can be divided by
2 (or 4, respectively) without remainder".
Then the above can go wrong
a) if the union has an address accommodating the alignment
requirement of int but not of long
b) sizeof (int) == 2: sizeof (long) > sizeof my_union, i.e.
the "CAST" accesses storage which does not belong to
my_union. This gives you either an arbitrary value for
longvar or an access to storage which does not belong
to your program
c) long has a trap representation which has been generated
using my_union.ch
d) a combination of a)-c)
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Feb 13 '06 #6

<ca********@yahoo.com> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com...
I recently came across the following CAST macro which can cast anything
to any other thing:

#define CAST(new_type,old_object) (*((new_type *)&old_object))
oh dear. Bracket in the wrong place -- needs to be

#define CAST(new_type,old_object) (*(new_type *)&(old_object))
or it won't always work.

(It won't work with array types either, but you can get round that with a
typedef)


union
{
char ch[4];
int i[2];
} my_union;

long longvar;

longvar = (long)my_union; Illegal cast
//////////////// ILLEGAL
longvar = CAST(long, my_union); Legal cast

I understands that why the CAST macro works but I cannot understands
that what is the problem in the following casting :

longvar = (long)my_union;


You can't convert a variable. You can only fetch its value and convert
that. But you can only do that with a scalar. Converting the "value" of an
array or struct or union doesn't make any sense

--
RSH

Feb 13 '06 #7
Robin Haigh wrote:
<ca********@yahoo.com> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com...
I recently came across the following CAST macro which can cast anything
to any other thing:

#define CAST(new_type,old_object) (*((new_type *)&old_object))


oh dear. Bracket in the wrong place -- needs to be

#define CAST(new_type,old_object) (*(new_type *)&(old_object))
or it won't always work.

(It won't work with array types either, but you can get round that with a
typedef)


What do you mean?

#include <stdio.h>

#define UNSAFE_CAST(new_type, old_object) \
(*((new_type *)&(old_object)))

int main (void)
{
short foo[5] = {42, 1, 2, 3, 4};

printf("&foo[0]: %p, &foo: %p\n",
(void *)&foo[0], (void *)&foo);
printf("foo[0]: %d\n", UNSAFE_CAST(short,foo));

return 0;
}

<snip!>

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Feb 13 '06 #8
ca********@yahoo.com wrote:

I recently came across the following CAST macro which can cast anything
to any other thing:

#define CAST(new_type,old_object) (*((new_type *)&old_object))

union
{
char ch[4];
int i[2];
} my_union;

long longvar;

longvar = (long)my_union; Illegal cast
//////////////// ILLEGAL
longvar = CAST(long, my_union); Legal cast

I understands that why the CAST macro works but I cannot understands
that what is the problem in the following casting :

longvar = (long)my_union;

Can somebody please tell me that what is the problem in the above
casting mechanism?

[...]

You cannot simply cast from a union to a long, which is what you are
trying to do with the direct cast.

However, the CAST() macro does not directly cast from a union to a
long. Rather, it takes the address of the union, casts that to a
"long *", and then dereferences the pointer.

CAST(long,my_union)

expands to

*(long *)&my_union

Note, of course, that the above is not a very "safe" thing to be doing.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Feb 13 '06 #9

"Michael Mair" <Mi**********@invalid.invalid> wrote in message
news:45************@individual.net...
Robin Haigh wrote:
<ca********@yahoo.com> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com...
I recently came across the following CAST macro which can cast anything
to any other thing:

#define CAST(new_type,old_object) (*((new_type *)&old_object))


oh dear. Bracket in the wrong place -- needs to be

#define CAST(new_type,old_object) (*(new_type *)&(old_object))
or it won't always work.

(It won't work with array types either, but you can get round that with a
typedef)


What do you mean?


I only meant, if new_type is int[3], you'll get (int[3]*), which will be a
syntax error. You can't always generate the name of a pointer type just by
adding a * on the end of something.

--
RSH
Feb 13 '06 #10
Robin Haigh wrote:
"Michael Mair" <Mi**********@invalid.invalid> wrote in message
news:45************@individual.net...
Robin Haigh wrote:
<ca********@yahoo.com> wrote in message
news:11**********************@g44g2000cwa.googl egroups.com...
I recently came across the following CAST macro which can cast anything
to any other thing:

#define CAST(new_type,old_object) (*((new_type *)&old_object))

oh dear. Bracket in the wrong place -- needs to be

#define CAST(new_type,old_object) (*(new_type *)&(old_object))
or it won't always work.

(It won't work with array types either, but you can get round that with a
typedef)


What do you mean?


I only meant, if new_type is int[3], you'll get (int[3]*), which will be a
syntax error. You can't always generate the name of a pointer type just by
adding a * on the end of something.


I see; thank you for the clarification :-)

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Feb 13 '06 #11
ca********@yahoo.com writes:
I recently came across the following CAST macro which can cast anything
to any other thing:

#define CAST(new_type,old_object) (*((new_type *)&old_object))

[...]

The name CAST is misleading. A C cast oerator specifies a
*conversion*. This macro reinterprets the operand's representation as
if it were of a specified type, which is a very different thing.
(Some conversions might be implemented that way, but numeric
conversions, for example, are not.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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.
Feb 13 '06 #12
Keith Thompson wrote:
ca********@yahoo.com writes:
I recently came across the following CAST macro which can cast anything
to any other thing:
Though not necessarily in a portable fashion.

#define CAST(new_type,old_object) (*((new_type *)&old_object)) [...]

The name CAST is misleading. A C cast oerator specifies a
*conversion*.


Yes. More specifically, a cast is an _explicit_ conversion. What could
be
more explicit than an all caps function macro that converts an lvalue
of
one type to an lvalue of another type?
This macro reinterprets the operand's representation as
if it were of a specified type, which is a very different thing.
Bjarne Stroustrup (a notable C programmer) didn't think so. He
labelled one of the C++ operators reinterpret_cast, not reinterpret
or reinterpret_conversion.
(Some conversions might be implemented that way, but numeric
conversions, for example, are not.)


As I see it, a conversion usually involves two things: a change of
type, and a mapping of representation. The latter being a no-op
does not mean the 'change' is not a 'conversion'.

Perhaps the point you want to make is that, in C, casts produce
(old school) rvalues, so maybe REINTERPRET_CAST or
REINTERPRET_AS would be a better name?

--
Peter

Feb 13 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
by: j0mbolar | last post by:
I was reading page 720 of unix network programming, volume one, second edition. In this udp_write function he does the following: void udp_write(char *buf, <everything else omitted) struct...
1
by: rahul8143 | last post by:
hello, In kernel source code there is ip_fragment.c file my question is regarding pointer function and casting for that look at required snippet from that file There is structure defined for...
61
by: Ken Allen | last post by:
I am relatively new to .Net, but have been using VB and C/C++ for years. One of the drawbacks with VB6 and earlier was the difficulty in casting a 'record' to a different 'shape' so one could...
2
by: Enrique Bustamante | last post by:
Casting arrays that works on watch and command window but not in code. My application is casting arrays in a way it should work. To test if I was doing something invalid, I wrote a test code that...
8
by: wkaras | last post by:
In my compiler, the following code generates an error: union U { int i; double d; }; U u; int *ip = &u.i; U *up = static_cast<U *>(ip); // error I have to change the cast to...
9
by: Roman Mashak | last post by:
Hello, All! I met this code recently on some open source sites. What may be the point of using such construction: typedef struct cmd { unsigned int cmdack; unsigned int code; unsigned int...
3
by: Tigger | last post by:
I have an object which could be compared to a DataTable/List which I am trying to genericify. I've spent about a day so far in refactoring and in the process gone through some hoops and hit some...
4
by: Schkhan | last post by:
Hi, I am sturggling with a peace of code mainly its about casting a pointer to one type of structure to a pointer to another type of structure. the confusion begins with the following...
101
by: Tinkertim | last post by:
Hi, I have often wondered if casting the return value of malloc() (or friends) actually helps anything, recent threads here suggest that it does not .. so I hope to find out. For instance : ...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.