473,382 Members | 1,258 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,382 software developers and data experts.

Noob Q: How to properly type cast in this case

Hi,

I couldn't figure out how to properly type cast in this case:

$ 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 i = 2;
32 markedplace->data.dp = NULL;
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

How should I fix it?

Thanks
--
Tong (remove underscore(s) to reply)
http://xpt.sourceforge.net/techdocs/
http://xpt.sourceforge.net/tools/
Jun 27 '08 #1
7 3920
* Tong * wrote:
Hi,

I couldn't figure out how to properly type cast in this case:
Why cast at all?
>
$ 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 i = 2;
32 markedplace->data.dp = NULL;
33 (Small_Int *)markedplace->data.dp = i;
markedplace->data.dg=&i;
Is probably what you should do.
34 }

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

How should I fix it?
Don't cast an lvalue. Avoid casts wherever possible.
Here use the address of i to set the value of dp, which is a (void) pointer.
Thanks
Bye, Jojo
Jun 27 '08 #2
Joachim Schmitz wrote:
* Tong * wrote:
<snip>
> 33 (Small_Int *)markedplace->data.dp = i;
markedplace->data.dg=&i;
Modulo typos...
markedplace->data.dp=&i;

I was concentrating to not write marketplace instead 8-)
Is probably what you should do.

Jun 27 '08 #3
Joachim Schmitz wrote:
Joachim Schmitz wrote:
>* Tong * wrote:
<snip>
>> 33 (Small_Int *)markedplace->data.dp = i;
markedplace->data.dg=&i;
Modulo typos...
markedplace->data.dp=&i;
If the original poster were trying to store the address of i in data.dp,
then the parents of this reply are correct. As they have stated, you
should write:

markedplace->data.dp = &i;

If however you are trying to store the value of i into one of bytes::d1,
::d2, ::d3, or ::d4, you should use the following:

markedplace->data.bytes.d1 = (Small_Int)i; // or {d2, d3, d4}

That said, this is a very unusual thing to want to do.

--
Andrew Kerr
Jun 27 '08 #4
Thanks for the reply Joachim and Andrew.

Sorry, I noticed that I've screwed my example, let me try again.

On Thu, 29 May 2008 16:41:47 +0200, Joachim Schmitz wrote:
>I couldn't figure out how to properly type cast in this case:
Why cast at all?
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? Line 32 was actually how I
fixed it, but I want to know how to properly type cast if I have to.

Thanks

--
Tong (remove underscore(s) to reply)
http://xpt.sourceforge.net/techdocs/
http://xpt.sourceforge.net/tools/
Jun 27 '08 #5
* Tong * <su**********@users.sourceforge.netwrote:
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@toerring.de
\__________________________ http://toerring.de
Jun 27 '08 #6
Thanks a lot for the step by step and comprehensive explanation.

On Thu, 29 May 2008 20:36:08 +0000, Jens Thoms Toerring wrote:
. . .
int i;
void *v = &i;

* ( int * ) v = 42;
. . .
Jun 27 '08 #7
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
Jun 27 '08 #8

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

Similar topics

4
by: Jacob Jensen | last post by:
This question has probably been asked a million time, but here it comes again. I want to learn the difference between the three type cast operators: static_cast, reinterpret_cast, dynamic_cast. A...
5
by: verec | last post by:
I just do not understand this error. Am I misusing dynamic_cast ? What I want to do is to have a single template construct (with no optional argument) so that it works for whatever T I want to...
25
by: hugo2 | last post by:
Obrhy/hugo July 12, 2004 Take a look at this memcpy() definition. Is there a good reason the void pointer args are cast to byte just to assign their addresses to byte pointers? /*from Steve...
5
by: zfeld | last post by:
How do I cast an object to its proper class at runtime given its System.Type I have code that looks like this: MyObject class has subclasses of MySubObjectA & MySubObjectB: MyObject obja =...
3
by: mra | last post by:
I want to cast an object that I have created from a typename to the corresponding type. Can anycone tell me how to do this? Example: //Here, Create the object of type "MyClass" object...
10
by: kar1107 | last post by:
Hi all, Can the compiler chose the type of an enum to be signed or unsigned int? I thought it must be int; looks like it changes based on the assigned values. Below if I don't initialize...
14
by: streamkid | last post by:
i'm a learning newbie at c++... and i have the following question... reading some source code, i saw this: int function(const void * one, const void * two) { int var1, var2; var1 =...
4
by: Arch Stanton | last post by:
I'm trying to bind data in a dataset (obtained from an Access DB) to a listbox in ASP.net. I know my dataset is being created properly because it displays fine in a datagrid, but I can't get it to...
2
by: Tom P. | last post by:
I'm not getting the theory behind LINQ, and without that I can't get my head around how to use it and why. Here's what I _think_ I'm trying to do: I've got a menu with several items. Some other...
1
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
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

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.