LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-03-2011, 07:43 AM   #1
Ramurd
Member
 
Registered: Mar 2009
Location: Rotterdam, the Netherlands
Distribution: Slackwarelinux
Posts: 703

Rep: Reputation: 111Reputation: 111
lvalue required as left operand of assignment


Hi all, it's been a long time since I did coding in C, but thought to pick up a very old project again, just to show off what I have been working on ten years ago.

I deducted my problem as follows:

Code:
#include <stdio.h>
#include <stdlib.h>

#define bit1 1
#define bit2 2
#define bit3 4
#define bit4 8
// etc .. ;-)

#define SET_BIT(var,bit) (((long long) (var) |= ((long long) (bit)))

typedef struct foo FOO;

struct foo
{
  int act;
}

int main(int argc, char *argv[])
{
  FOO *bar;

  bar=calloc(1,sizeof(FOO));
  bar->act = 0;
  printf("act: %d\n", bar->act);
  SET_BIT(bar->act,bit3);
  printf("act: %d\n",bar->act);

  return 0;
}
Now I get an error when compiling (gcc 4.3.3 under Linux, 32-bit):
Quote:
lvalue required as left operand of assignment
this is on the line
Code:
SET_BIT(bar->act,bit3);
I am 100% certain that this used to compile fine in the past (10 years ago :-o);

Why is it saying that bar->act is not a valid lvalue while both bar->act and the bit are cast to (long long)?
 
Old 02-03-2011, 08:09 AM   #2
Ramurd
Member
 
Registered: Mar 2009
Location: Rotterdam, the Netherlands
Distribution: Slackwarelinux
Posts: 703

Original Poster
Rep: Reputation: 111Reputation: 111
funnily enough:
if I change
Code:
SET_BIT(bar->act,bit3);
into

Code:
bar->act |= bit3;
it's perfectly valid, but when I change it into:

Code:
(long long}bar->act |= (long long)bit3
I get the error back... it seems the typecast is what upsets gcc.

Ideally, I'd rewrite the SET_BIT macro so that it will be accepted again, so that I don't have to go through thousands of lines of code to fix this...

Edit:
It would seem obvious to remove the cast from the SET_BIT macro; However, I'd have to analyze and see how and why. Naturally, I'm a lazy person as far as this goes, so what I'm curious about is why the cast appears to be invalid. (It's fairly possible that this SET_BIT is used elsewhere on a char, or maybe even a float or double... again: It will take a fair amount of going hence and forth in the code.) So: how could I safely typecast both the var and bit so that either is accepted as lvalue and rvalue respectively?

Last edited by Ramurd; 02-03-2011 at 09:51 AM.
 
Old 02-03-2011, 09:43 AM   #3
ForzaItalia2006
Member
 
Registered: Dec 2009
Location: Walldorf, Germany
Distribution: (X)Ubuntu, Arch, Gentoo
Posts: 205

Rep: Reputation: 67
Hey Ramurd,

great that you got back to C programming :-)

Regarding your problem, this error message is correct and as expected. If you look into the C99 standard, you'll find the following section about cast expressions:

Quote:
6.5.4 Cast operators
[...]
4 Preceding an expression by a parenthesized type name converts the value of the
expression to the named type. This construction is called a cast. (footnote 89)

(footnote 89) A cast does not yield an lvalue. Thus, a cast to a qualified type has the same effect as a cast to the
unqualified version of the type
Though, a cast is not valid on the left side of an assignment.

Andi
 
1 members found this post helpful.
Old 02-03-2011, 10:04 AM   #4
Ramurd
Member
 
Registered: Mar 2009
Location: Rotterdam, the Netherlands
Distribution: Slackwarelinux
Posts: 703

Original Poster
Rep: Reputation: 111Reputation: 111
Hey Forza,

Thanks; It's pretty obvious when I stopped actively coding ;-) That was around 1999, hence I did not get that standard. Thanks for pointing out that I should look at the standards. While not the answer I hoped for, (I guess I'll have to try and see if removing the casts will result in big issues), I'm glad you pointed it out.

Back to programming... (oh, and I noticed I "forgot" to free(bar) in the quick-and-dirty example... :-)
 
Old 02-03-2011, 03:57 PM   #5
gothrog
Member
 
Registered: Jun 2004
Distribution: Yellow Dog, Fedora, RedHat, Centos, Ubuntu, Suse Linux
Posts: 106

Rep: Reputation: 15
I'm not sure what you are doing at a physical layer, but if you can break bits into a byte and throw them into an array you could use a ptr to an address.

I think your trying to OR the bits together to get some datatype

In this example 'payload' is the array.
Code:
            for ( int inc = 0; inc < theSize3; inc++ )
            {
               *(payload + buffCount + inc ) = outStr3[inc];
               cout << payload[buffCount + inc];
            }
            cout << endl;
            buffCount = buffCount + theSize3;

Last edited by gothrog; 02-03-2011 at 03:58 PM.
 
Old 02-03-2011, 05:49 PM   #6
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,012

Rep: Reputation: 115Reputation: 115
Code:
#define SET_BIT(var,bit) do { ((*(unsigned long long*) &(var) |= ((unsigned long long)1 << (bit))); } while(0)
 
1 members found this post helpful.
Old 02-04-2011, 04:35 AM   #7
Ramurd
Member
 
Registered: Mar 2009
Location: Rotterdam, the Netherlands
Distribution: Slackwarelinux
Posts: 703

Original Poster
Rep: Reputation: 111Reputation: 111
Thanks all for giving some neat solutions and answers; should've come up with tuxdev's approach;

For now I ended up with:
Code:
#define SET_BIT(var,bit) ((*(long long*) &(var) |= ((long long)(bit))))
due to the signedness of the variables I've seen so far.

So what I can do now is this:
Code:
#include <stdlib.h>
#include <stdio.h>

#define bit1 1
#define bit2 2
#define bit3 4
#define bit4 8
#define bit5 16
#define bit6 32
#define bit7 64
#define bit8 128
#define bit9 256
#define bit10 512

#define SET_BIT(var,bit) ((*long long*) &(var) |= ((long long) (bit))))

typedef struct foo FOO;

struct foo
{
  int act;
}

int main(int argc, char *argv[])
{
FOO *bar;

bar=calloc(1,sizeof(FOO));

bar->act = 0;
printf("act: %d\n", bar->act);
SET_BIT(bar->act,bit3);
SET_BIT(bar->act,bit5);
printf("act: %d\n", bar->act);

free(bar);
return 0;
}
this will correctly return:
Quote:
act: 0
act: 20
I am aware that by shifting bits I could accomplish the same; however for simplicity's sake, I have also these macro's:
Code:
#define IS_SET(flag,bit) (flag & bit)
#define REMOVE_BIT(var,bit) ((*(long long *) &(var) &= ~((long long)(bit))))
#define TOGGLE_BIT(var,bit) ((*(long long *) &(var) ^= ((long long)(bit))))
These macro's allow for quick checking of a certain bit-flag.
The usage is in terms of
Code:
#define RECORD_DIRTY 1
#define RECORD_TYPE_TEXT 2
#define RECORD_TYPE_DATA 4
#define RECORD_TYPE_MULTIPART (RECORD_TYPE_TEXT|RECORD_TYPE_DATA) //  = 6
#define RECORD_EXPIRED 8
so, one reads only 1 (long long) integer, which is quite fast and perform certain checks based on that single integer; since it's a bitwise check/set, the method is also fairly fast and consumes little memory. There are various records with various types (all integer-based); so that these macro's are indeed widely usable.

I tagged the helpful posts as I noticed they helped me find a good solution, and quite happy that tuxdev showed how to work around the lvalue limitation regarding type casts. And marked the thread as solved. I guess this is material one does not easily figures out without some (fresh) hands-on experience. :-)
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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 Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
invalid lvalue in assignment cdw9997 Programming 9 05-05-2009 06:16 PM
lvalue operator / consumable objects ta0kira Programming 8 10-23-2008 09:27 PM
error: invalid lvalue in assignment nasim751 Programming 3 04-10-2008 01:59 PM
Error: invalid lvalue in assignment xxrsc Linux - Software 1 08-17-2006 01:43 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:37 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration