On Thu, 29 May 2008 09:33:31 -0500, * Tong *
<su**********@users.sourceforge.netwrote:
>Hi,
I couldn't figure out how to properly type cast in this case:
There is no such thing as type cast in C. There is only cast.
Furthermore, you cannot cast objects, only values.
>
$ cat -n type_cast.c
1 #include <stdio.h>
By including these line numbers, you have made it annoyingly difficult
for anyone to compile your code.
2
3 typedef unsigned char Byte;
4 typedef signed char Small_Int;
5
6 typedef struct _list
7 {
8 struct _list *np; /* Pointer to next */
9 struct _list *lp; /* Pointer to last */
10 Byte type;
11 union {
12 void *dp; /* Pointer to data */
13
14 /* These fields used for a small amount of data */
15 struct {
16 Byte d1;
17 Byte d2;
18 Byte d3;
19 Byte d4;
20 } bytes;
21
22 }data;
23
24 } List;
25
26 List *markedplace;
markedplace is a pointer defined at file scope. As such, it has
static duration and is initialized to NULL. That means it does not
point to memory you own.
27 Small_Int i;
28
29 main(int argc,char * argv[])
Implicit int has been removed from C99. Better to specify it
explicitly as in
int main(...
30 {
31 i = 2;
32 markedplace->data.dp = NULL;
Here you attempt to dereference markedplace via the -operator.
Dereferencing a pointer that does not point to memory you own invokes
undefined behavior.
33 (Small_Int *)markedplace->data.dp = i;
Wrong in so many so many different ways.
You still cannot dereference markedplace as noted above.
The -operator has higher precedence than cast operator. The left
hand side is parsed as if it were (Small_Int *)(markedplace->data.dp).
The cast does not change the type of markedplace->data.dp. If it did
anything it would convert its value to the new type. Consequently,
the expression does not represent an object into which you can store a
value. (That is what the compiler is trying to tell you in the error
message about an lvalue required.) So the answer to the implied
question at the top of your post is "There is no way to cast the left
operand of the assignment operator."
If the left hand side could evaluate to an lvalue, it would have a
pointer type. i is an integer. Assigning an integer to a pointer is
a constraint violation requiring a diagnostic. In this case, even if
the compiler were to generate the correct code to convert the value in
i to a pointer, the result would be pretty much useless.
34 }
main returns an int. So do so.
>
$ gcc type_cast.c
type_cast.c: In function 'main':
type_cast.c:33: error: lvalue required as left operand of assignment
First you should insure that markedplace points to a structure.
Alternately, you could change markedplace from a pointer to an actual
struct by removing the * from its definition. Then you would replace
all the -operators with . operators.
Since data.dp is a void*, it is capable of holding the address of any
object and there is an implicit conversion in both directions between
pointers to void and pointers to any type of object. Therefore no
cast is needed and your code should look something like
markedplace->data.dp = &i;
Remove del for email