Thread: error: lvalue required, pretty sure it's an lvalue

  1. #1
    Registered User
    Join Date
    Aug 2011
    Posts
    2

    error: lvalue required, pretty sure it's an lvalue

    Hey, super-duper beginner question time. I'm writing a program to convert decimal (a defined variable x) to binary by testing for division by powers of 2^y for some digits corresponding to 0<=y<=15. When I compile I'm getting

    error: lvalue required as left operand of assignment

    I did a little research and found that an lvalue is the kind of value output by operators like == and <. I think. Here's my code.

    Code:
    	for(y=14; y>0; y--){
    		printf("%d", x/(2^y));
    		(x/(2^y))==0 ? : x/=(2^y);
    	}
    The third line is the one of interest. I also tried putting stuff between the question mark and the colon to make sure that wasn't the "left operand" it's referring to. I don't think it is. But doesn't (x/(2^y))==0 return an lvalue? I'm confused. Some help would be appreciated.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Well firstly, ^ isn't "raise to power of", it's bitwise exclusive-or

    And your ?: line should be something like
    boolean_expression ? expression_if_true : expression_if_false

    You have nothing between ? :
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    An lvalue is simply something that can be on the left side of =. Looking at your code, the only thing on the left side of = is an x, so make sure you didn't do something like make x a constant. (In addition to the whole ^ thing as mentioned above.)

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by Salem View Post
    You have nothing between ? :
    Actually, some compilers allow that as an extension: ?: - Wikipedia, the free encyclopedia.

    @OP:
    It seems the following is the culprit:
    Code:
    (x/(2^y))==0 ? : x/=(2^y);
    For some reason, the compiler wont allow you to assign something to x with a /= inside the ternary operator. I don't know what the standard says on this, but I feel like your code should be valid, even if it is totally wonky.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by anduril462
    For some reason, the compiler wont allow you to assign something to x with a /= inside the ternary operator. I don't know what the standard says on this, but I feel like your code should be valid, even if it is totally wonky.
    The problem could be that the conditional operator has a higher precedence than operator /=. As such, the statement could be written as:
    Code:
    ((x / (2 ^ y)) == 0 ? : x) /= (2 ^ y);
    Note that a conditional expression does not yield an lvalue.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    EDIT: Interesting follow up. I'm using gcc 4.4.5 on Fedora 13.
    Code:
    #include <stdio.h>
    
    
    int main(void)
    {
        int x = 17;
        x ? 42 : x++;
        x ? 42 : x += 1;
        x ? 42 : x = x + 1;
        return 0;
    }
    The first version, with x++, passes the compiler, but the last two give the "lvalue required" error. Is there something fundamentally different that I'm not aware of between those 3 statements? Semantically, they're all the same (they increment x by 1 if x is zero). Furthermore, all 3 of the following work:
    Code:
    #include <stdio.h>
    
    
    int main(void)
    {
        int x = 17;
        x ? x++ : 42;
        x ? x += 1 : 42;
        x ? x = x + 1 : 42;
        return 0;
    }
    I'm not saying any of that is good code, but the inconsistency bothers me.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by anduril462
    The first version, with x++, passes the compiler, but the last two give the "lvalue required" error. Is there something fundamentally different that I'm not aware of between those 3 statements? Semantically, they're all the same (they increment x by 1 if x is zero).
    It seems that you completely ignored my post
    Try:
    Code:
    #include <stdio.h>
    
    
    int main(void)
    {
        int x = 17;
        x ? 42 : x++;
        x ? 42 : (x += 1);
        x ? 42 : (x = x + 1);
        return 0;
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by laserlight View Post
    The problem could be that the conditional operator has a higher precedence than operator /=. As such, the statement could be written as:
    Code:
    ((x / (2 ^ y)) == 0 ? : x) /= (2 ^ y);
    Not quite. The OP's version only divides x by (2 ^ y) if ((x / (2 ^ y)) is non-zero, otherwise x is unchanged. Your version does the division regardless of the value of ((x / (2 ^ y)). I think you would want
    Code:
    x = (x / (2 ^ y)) == 0 ? : x / (2 ^ y);
    Note that a conditional expression does not yield an lvalue.
    Thanks, noted. And I found the relevant portion of the standard (C99 6.5.15):
    Code:
    conditional-expression:
        logical-OR-expression
        logical-OR-expression ? expression : conditional-expression
    So that somewhat explains why all 3 versions of incrementing x in the "true" clause are accepted while not in the "false" clause, since conditional expressions don't yield an lvalue. But that begs the question: why do you have an expression if true and a conditional-expression if false?

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by anduril462
    The OP's version only divides x by (2 ^ y) if ((x / (2 ^ y)) is non-zero, otherwise x is unchanged. Your version does the division regardless of the value of ((x / (2 ^ y)).
    No, the OP's version does the division regardless of the value of ((x / (2 ^ y)), if it were correct in the first place. You only think otherwise because you are not aware of the precedence rules.

    Quote Originally Posted by anduril462
    But that begs the question: why do you have an expression if true and a conditional-expression if false?
    Probably so that (a ? b : c ? d : e) would be equivalent to (a ? b : (c ? d : e)).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by laserlight View Post
    It seems that you completely ignored my post
    Nope, but I had written 95% of my response, and got distracted at work. I hit post not realizing you had replied
    Try:
    Code:
    #include <stdio.h>
    
    
    int main(void)
    {
        int x = 17;
        x ? 42 : x++;
        x ? 42 : (x += 1);
        x ? 42 : (x = x + 1);
        return 0;
    }
    Ahh, that explains that bit to me. Thanks!

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by laserlight View Post
    No, the OP's version does the division regardless of the value of ((x / (2 ^ y)), if it were correct in the first place. You only think otherwise because you are not aware of the precedence rules.
    Okay, I'm confused:
    Quote Originally Posted by C99 6.5.15p4
    The first operand is evaluated; there is a sequence point after its evaluation. The second
    operand is evaluated only if the first compares unequal to 0; the third operand is evaluated
    only if the first compares equal to 0; the result is the value of the second or third operand
    (whichever is evaluated), converted to the type described below.93) If an attempt is made
    to modify the result of a conditional operator or to access it after the next sequence point,
    the behavior is undefined.
    Am I misunderstanding? It sounds like the false clause is only evaluated if the condition evaluates to false.
    EDIT: And the = and += operator are lower precedence than the ?:, which also introduces a sequence point, so the += should happen later, and only if the condition is false.

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by anduril462
    Am I misunderstanding? It sounds like the false clause is only evaluated if the condition evaluates to false.
    That is correct. However, this is the conditional operator expression in the original post:
    Code:
    (x/(2^y))==0 ? : x
    Notice that there is no operator /= involved.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So if true the expression expands to
    /= 2^y
    and if false it expands to
    x /= 2^y

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by tabstop
    and if false it expands to
    x /= 2^y
    Not exactly, because we are dealing with an operator, not a macro. Although we could see it in terms of an "expansion", the x here is not an lvalue.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by laserlight View Post
    That is correct. However, this is the conditional operator expression in the original post:
    Code:
    (x/(2^y))==0 ? : x
    Notice that there is no operator /= involved.
    Right. My point was the OP wanted the result of that division to be assigned to x only if the result was non-zero. Your rewrite of the expression in post #5 always returns x (due to the GNU extension with the empty true clause), regardless of whether x/(2^y) == 0. x is then divided by (x/(2^y)).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. error: lvalue required as left operand of assignment
    By owjian1987 in forum C Programming
    Replies: 5
    Last Post: 02-11-2011, 12:34 PM
  2. Replies: 3
    Last Post: 06-01-2010, 06:22 AM
  3. Lvalue required error
    By Dink87522 in forum C Programming
    Replies: 4
    Last Post: 10-04-2009, 08:34 PM
  4. Lvalue required error
    By eklavya8 in forum C Programming
    Replies: 5
    Last Post: 01-03-2009, 04:47 PM
  5. Lvalue required --compile error--
    By cecu in forum C++ Programming
    Replies: 2
    Last Post: 05-19-2006, 07:40 PM