Re: Noob Q: How to properly type cast in this case



* Tong * <sun_tong_001@xxxxxxxxxxxxxxxxxxxxx> wrote:
I am trying to compile a big program, in which the following line gives me
the "lvalue required" error:

(Small_Int *)markedplace->data.dp = p;

The following is what I stripped out for the illustration purpose:

$ cat -n type_cast.c
1 #include <stdio.h>
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;
27 Small_Int i;
28
29 main(int argc,char * argv[])
30 {
31 markedplace->data.dp = NULL;
32 markedplace->data.dp = &i;
33 (Small_Int *)markedplace->data.dp = &i;
34 }

$ gcc type_cast.c
type_cast.c: In function 'main':
type_cast.c:33: error: lvalue required as left operand of assignment

So we don't need to type cast for void pointers?

Every pointer to a object (but not functions) can be converted
to a void pointer and back again without problems (and even
without an explicit cast). The assignment

markedplace->data.dp = &i;

implicitely converts the value of the right side (which is a pointer
to a 'Small_Int') to a void pointer as if you had written explicitely

markedplace->data.dp = ( void * ) &i;

But you can't cast the left hand side. It stays a void pointer
whatever you do. If it would work otherwise why shouldn't also
e.g.

int x = 13;

( double ) x = 3.1419265359;

work in changing 'x', so it suddenly has a type of double?

Actually, the cast on the left hand side takes the value
stored in 'x' and converts that value to a double. And after
this operation the compiler suddenly sees

13.0 = 3.1419265359;

and complains rightly about "lvalue required as left operand
of assignment" since now you have something on the left hand
side that isn't something a value could be assigned to since
it's already a value.

Line 32 was actually how I
fixed it, but I want to know how to properly type cast if I have to.

By only casting values, not trying to "cast" objects. If you
do e.g.

int x;
double pi = 3.1419265359;

x = ( int ) pi;

you don't cast the variable 'pi', you only cast the value that
is stored in the 'pi'. So it's a valid cast since it doesn't try
to change anything about the type of 'pi'. And if you do e.g.

int i;
void *v = &i;

* ( int * ) v = 42;

then again you cast the value stored in 'v' (not 'v' itself) to
an int pointer and then write 42 to that address. As you see, a
cast can also appear on the left hand side, but only if a value
is acceptable at that place on the left hand side.

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@xxxxxxxxxxx
\__________________________ http://toerring.de
.



Relevant Pages

  • Re: Function pointer cast
    ... Sometimes this points to an int location containing the address of a ... How can I cast it so that I can call that function? ... which might be more readable with a typedef (I dislike ... Be aware that treating an int value as a function pointer ...
    (comp.lang.c)
  • Re: operator precedence
    ... > - typecast the void pointer into a type pointer ... But since ++ has precedence over the type cast ... I don't see why the result of (int *) wouldn't be an l-value. ...
    (comp.std.c)
  • Re: Correct way to cast
    ... The HMENU is a platform-specific extension (probably a typedef), ... and I really doubt that a cast to int is legal on said platform. ...
    (comp.lang.c)
  • Re: Newbie question about malloc
    ... "Implicit int" no longer exists in C. ... It's generally recommended to NOT cast the return from malloc. ... %d can never be the correct format specifier for a size_t. ... C99 introduced %zu for this purpose, ...
    (comp.lang.c)
  • Re: what will happen after i use free()???
    ... Inserting a cast before malloc is not needed, ... 56 bits while int is only 48 bits. ... So casting that value requires some ... Use cast only if you are absolutely sure that yor really needs the ...
    (comp.lang.c)