- Stack Overflow Public questions & answers
- Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
- Talent Build your employer brand
- Advertising Reach developers & technologists worldwide
- Labs The future of collective knowledge sharing
- About the company
Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Assignment statement used in conditional operators
Can anybody please tell me why this statement is giving an error - Lvalue Required
but this one is correct
where a , b and g are integer variables , and a and b are taken as input from keyboard.
- 6 Why not to use g = a > b ? a : b ? – m0nhawk Jul 28, 2013 at 8:12
- @m0nhawk good point. But may be because OP come from c++. – Grijesh Chauhan Jul 28, 2013 at 8:23
- 1 @m0nhawk: Wouldn't lead to such an interesting question. It's a rather nice case of easy to avoid mistakes you might not notice just by reading your code. I think it would even compile fine as C++, because ?: and = got the same precedence there. Still doesn't mean you should necessarily do it, as it can cause confusion and "unexpected" behavior. – Mario Jul 28, 2013 at 8:23
6 Answers 6
In the expression,
the relational operator > has the highest precedence, so a > b is grouped as an operand. The conditional-expression operator ? : has the next-highest precedence. Its first operand is a>b , and its second operand is g = a . However, the last operand of the conditional-expression operator is considered to be g rather than g = b , since this occurrence of g binds more closely to the conditional-expression operator than it does to the assignment operator . A syntax error occurs because = b does not have a left-hand operand (l-value). You should use parentheses to prevent errors of this kind and produce more readable code which has been done in your second statement
in which last operand g = b of : ? has an l-value g and thats why it is correct.
Alternatively you can do
- 1 you explained with precedence that is better, actually grammar written using precedence rules. --high precedence operators should be added later such that the appear towards leaf node in evaluation tree. Got it?? – Grijesh Chauhan Jul 28, 2013 at 8:41
- @GrijeshChauhan; Please rephrase your sentence high precedence operators should be added later such that the appear towards leaf node in evaluation tree . I do not understand. – haccks Jul 28, 2013 at 8:43
- Read this answer I explained how to arrange operators in grammars such that high precedence operators evaluate first--I think it will help perfectly. – Grijesh Chauhan Jul 28, 2013 at 8:50
- @GrijeshChauhan; I read that answer on the link you provided. This is just because of Grammar . – haccks Jul 28, 2013 at 9:46
- as recent discussion between me and Mario: I found precedence(?:) == precedence(=) so you added correct last link. – Grijesh Chauhan Jul 28, 2013 at 10:03
And we can't assign to an expression so its l-value error.
Read: Conditional operator differences between C and C++ Charles Bailey's answer:
Grammar for ?: is as follows:
This means that a ? b : c = d parses as (a ? b : c) = d even though (due to the 'not an l-value' rule) this can't result in a valid expression.
One side note:
Please keep space in you expression so that it become readable for example.
Should be written as:
similarly, you should add space after ; and , .
- Can you please explain me the reason – john fedric Jul 28, 2013 at 8:07
- @user2132128 " lvalue " is something that might appear on the left side. It is something that can be assigned. For example, you can't do 3 = x; . – Maroun Jul 28, 2013 at 8:09
- 1 @MarounMaroun "lvalue" is something that might appear on the left side" - correct. - "It is something that can be assigned" - wrong. Those are "modifiable lvalues". const objects and arrays are also lvalues, yet they cannot be assigned to. – user529758 Jul 28, 2013 at 8:11
- 1 @GrijeshChauhan I'm here to help :) (to help those who deserve it, anyway...) Eh, and take my upvote for making the effort quoting the CFG of the conditional operator! – user529758 Jul 28, 2013 at 8:13
- 1 @GrijeshChauhan; Coating standard or grammar is good practice but not a good idea in case of newbie. – haccks Jul 28, 2013 at 8:38
The problem is operator precedence : In C the ternary conditional operator ( ?: ) has a higher precedence than the assignment operator ( = ).
Without parenthesis (which don't do anything here) your expression would be this:
The operator with the highest precedence in there would be the comparison > , so this is where you'll get your first logical grouping:
The next highest expression is the ternary conditional, which results in the following expression:
As you can see, you'll now end up with an lvalue (i.e. a value; not a variable) on the left side of your assignment operator, something that won't work.
As you already noticed, the solution to this is to simply group the expressions on your own. I'd even consider this good practice, especially if you're unsure how your precedence might play out. If you don't want to think about it, add parenthesis. Just keep code readability in mind, so if you can, resolve the operator precedence on your own, to ensure you've got everything right and readable.
As for readability: I'd probably use a classic if() here or move the assignment operator outside the ternary conditional, which is how you usually define max() :
Or more general as a macro or inline function:
- 1 explaining using precedence is better approach for new guys! – Grijesh Chauhan Jul 28, 2013 at 8:43
- 1 Mario but problem is this explanation is confusing if you think C/C++ together because according to precedence in C++ also precedence(?:) > precedence(=) but (a>b?g=a:g=b); is a valid expression. – Grijesh Chauhan Jul 28, 2013 at 8:57
- 1 @JensGustedt Yes, but Mario is not new-guy so I can discuss with him, as I am explaining to hakssc also. Yes here both answered are better explained mine :) – Grijesh Chauhan Jul 28, 2013 at 9:07
- 1 @GrijeshChauhan The precedence in C++ is different to C. Check the table again, both have 15 , which means they're evaluated right to left. Compare that table to the C one. The expression would work in C++, but it won't work in C. – Mario Jul 28, 2013 at 9:56
- 1 @Mario Yes you are correct! I was incorrect... Read this Order of Evaluation vs. Associativity also a good read] – Grijesh Chauhan Jul 28, 2013 at 10:01
that can be replaced with this
- 1 I like this solution, it provides a saner alternative. – user529758 Jul 28, 2013 at 8:14
- That doesn't really answer the question. – melpomene Jan 28, 2017 at 16:05
Your expression (a>b?g=a:g=b) is parsed as :
From the Microsoft documentation :
In C, the operator ?: has an higher precedence that the operator = . Then it means that ( a ? b : c = d ) will be parsed as ( a ? b : c ) = d . Due to l-value's rule, the first expression is also valid but is not doing what you think.
To avoid this error, you can do also :
- Please explain me the reason , why it is parsed as : (a>b?g=a:g)=b – john fedric Jul 28, 2013 at 8:10
- @user2132128 Again: the grammar of the C language defines it to be parsed like this. – user529758 Jul 28, 2013 at 8:12
- Your link leads to C++ documentation and a grammar snippet is taken from C++ grammar. This question is about C language. C language grammar is significantly different from C++ language grammar in this specifc regard. It is not possible to parse the original expression in C grammar. – AnT stands with Russia Jul 6, 2017 at 0:24
This question usually triggers a barrage of answers trying to explain the situation through the concept of operator precedence . In reality it cannot be explained that way, since this is a typical example of an input, on which surrogate concepts like "operator precedence" break down. As you probably know, there's really no "operator precedence" in C. There are only grammatical groupings, which generally cannot be expressed precisely through any linear ordering of operators.
Let's take a look at what the language specification says about it. The relevant portions of C grammar in this case are the grammars of ?: operator and = operator. For ?: operator it is
and for the = operator it is
In the first case the critical part is the last operand of ?: operator: it is not an expression , but rather a conditional-expression . The conditional-expression is a different entry point into the grammar of C expression: it "enters" the grammar at the point where it is no longer possible to include a top-level = operator into a conditional-expression . The only way to "smuggle" a = operator into a conditional-expression is to descend the grammar all the way to the very bottom
and then wrap around all the way to the top using the ( expression ) branch. This means that a conditional-expression can contain a = operator only when it is explicitly wrapped in (...) . E.g. the grammar prohibits you from having g = b as the last operand of ?: operator. If you want something like that, you have to explicitly parenthesize it: <smth> ? <smth> : (g = b) .
A very similar situation exists with the second piece of grammar: assignment operator. The left-hand side (LHS) of assignment is unary-expression . And unary-expression "enters" the general grammar of C expression at the point where it is too late to include a top level ?: operator. The only way to reach the ?: operator from unary-expression is to descend all the way down to primary-expression and take the ( expression ) branch. This means that grammar prohibits you from having a > b ? g = a : g as the LHS operand of = operator. If you want something like that, you have to explicitly parentesize it: (a > b ? g = a : g) = <smth> .
For this reason "popular" answers claiming that "operator precedence" makes the language to parse your expression as
are actually completely incorrect. In reality, there's no derivation tree in formal C grammar that would make your input fit the syntax of C language. Your input is not parsable at all. It is not an expression. It is simply syntactically invalid. C language sees it as a syntactic gibberish.
Now, in practice you might see some implementations to respond with a "lvalue required as left operand of assignment" diagnostic message. Formally, this is a misleading diagnostic message. Since the above input does not satisfy the grammar of C language expression , there's no "assignment" in it, there's no "left operand" and there's no meaningful "lvalue" requirement.
Why do compilers issue this strange message? Most likely they do indeed parse this input as a valid C expression
The result of ?: is never an lvalue in C, hence the error. However, this interpretation of your input is non-standard (extended?) behavior, which has no basis in formal C language. This behavior of specific implementations might be caused by their attempts to reconcile C and C++ grammars (which are quite different in this area), by their attempts to produce a more readable (albeit "fake") error message or by some other reason.
Typically, in such implementations a similar issue also would pop up in case of inputs like
The same error would be issued, suggesting a (a + b) = 5 parse, while from the pedantic point of view a + b = 5 is not parsable as an expression at all (for the same reasons as described above).
Again, formally, this is not enough to say that the compiler is "broken": the compiler is required to detect a constraint violation and issue some diagnostic message, which is exactly what happens here. The fact that the text of the diagnostic message does not correctly reflect the nature of the problem is inconsequential (the compiler can simply say "Ha ha ha!"). But one undesirable consequence of such misleading diagnostics is that it misleads users into misinterpreting the problem, which is BTW painfully evident from the barrage of formally incorrect answers posted to this question.
Sign up or log in, post as a guest.
Required, but never shown
Not the answer you're looking for? Browse other questions tagged c or ask your own question .
- The Overflow Blog
- If you want to address tech debt, quantify it first
- Fighting comment spam at Facebook scale (Ep. 602)
- Featured on Meta
- Moderation strike: Results of negotiations
- Our Design Vision for Stack Overflow and the Stack Exchange network
- Call for volunteer reviewers for an updated search experience: OverflowAI Search
- Temporary policy: Generative AI (e.g., ChatGPT) is banned
- Discussions experiment launching on NLP Collective
Hot Network Questions
- How to type this character from 汉字大字典 in my computer?
- ZX Spectrum+ 48K with faulty memory writing address
- C++20's std::views::filter not filtering the view correctly
- Why is there a voltage difference between these two grounds?
- What do Americans say instead of “can’t be bothered”?
- Is there any way to find the distance covered by a train in a particular rail route between two stations?
- Best-Practice in word-embeddings
- Is declining an offer to give a talk at a conference halfway around the world a bad idea?
- Is "abreast a" something ever correct?
- Writing multiline equation in align environment -> integrals become smaller?
- Isn't strong ignorability an incorrect assumption in complex causal structures?
- 13 puzzles I like
- What does в сложн. сл. mean in Russian dictionary?
- Sustainable eating habits as a pilot
- So, too, may be the fate of his seed
- What computer is this, a clone of a ZX Spectrum?
- Looking for a series of books that starts with a girl looking in her fridge, realizing she doesn’t like what’s in there and switches it
- Should I use fiber grip or grease when installing a bottom bracket into a carbon frame?
- Electromotive force computation and induced current
- People who can't receive O negative blood?
- Why is 50% black/white is 128, and not 127?
- Is there a socially-optimal way to drive on a busy interstate?
- How to have my hair cut?
C Data Types
- C Operators
- C Input and Output
- C Control Flow
- C Functions
- C Preprocessors
C File Handling
- C Cheatsheet
C Interview Questions
- Write an Interview Experience
- Share Your Campus Experience
- C Programming Language Tutorial
- C Language Introduction
- Features of C Programming Language
- C Programming Language Standard
- C Hello World Program
- Compiling a C Program: Behind the Scenes
- Tokens in C
- Keywords in C
C Variables and Constants
- C Variables
- Constants in C
- Const Qualifier in C
- Different ways to declare variable as constant in C and C++
- Scope rules in C
- Internal Linkage and External Linkage in C
- Global Variables in C
- Data Types in C
- Literals in C/C++ With Examples
- Escape Sequence in C
- Integer Promotions in C
- Character arithmetic in C and C++
- Type Conversion in C
- Basic Input and Output in C
- Format Specifiers in C
- printf in C
- Scansets in C
- Formatted and Unformatted Input/Output functions in C with Examples
- Operators in C
- Arithmetic Operators in C
- Unary operators in C/C++
- Operators in C | Set 2 (Relational and Logical Operators)
- Bitwise Operators in C/C++
- C Logical Operators
- Assignment Operators in C/C++
- Increment and Decrement Operators in C
Conditional or Ternary Operator (?:) in C
- sizeof operator in C
- Operator Precedence and Associativity in C
C Control Statements Decision-Making
- Decision Making in C / C++ (if , if..else, Nested if, if-else-if )
- C – if Statement
- C if…else Statement
- C if else if ladder
- Switch Statement in C
- Using range in switch case in C/C++
- C – Loops
- while loop in C
- do…while Loop in C
- For Versus While
- Continue Statement in C
- Break Statement in C
- goto Statement in C
- User-Defined Function in C
- Parameter Passing Techniques in C/C++
- Function Prototype in C
- How can I return multiple values from a function?
- main Function in C
- Implicit return type int in C
- Callbacks in C
- Nested functions in C
- Variadic functions in C
- _Noreturn function specifier in C
- Predefined Identifier __func__ in C
- C Library math.h Functions
C Arrays & Strings
- Properties of Array in C
- Multidimensional Arrays in C
- Initialization of a multidimensional arrays in C/C++
- How Arrays are Passed to Functions in C/C++?
- How to pass a 2D array as a parameter in C?
- What are the data types for which it is not possible to create an array?
- How to pass an array by value in C ?
- Strings in C
- Array of Strings in C
- What is the difference between single quoted and double quoted declaration of char array?
- C String Functions
- Pointer Arithmetics in C with Examples
- C – Pointer to Pointer (Double Pointer)
- Function Pointer in C
- How to declare a pointer to a function?
- Pointer to an Array | Array Pointer
- Difference between constant pointer, pointers to constant, and constant pointers to constants
- Pointer vs Array in C
- Dangling, Void , Null and Wild Pointers
- Near, Far and Huge Pointers in C
- restrict keyword in C
C User-Defined Data Types
- C Structures
- dot (.) Operator in C
- Structure Member Alignment, Padding and Data Packing
- Flexible Array Members in a structure in C
- Bit Fields in C
- Difference Between Structure and Union in C
- Anonymous Union and Structure in C
- Enumeration (or enum) in C
C Storage Classes
- Storage Classes in C
- extern Keyword in C
- Static Variables in C
- Initialization of static variables in C
- Static functions in C
- Understanding “volatile” qualifier in C | Set 2 (Examples)
- Understanding “register” keyword in C
C Memory Management
- Memory Layout of C Programs
- Dynamic Memory Allocation in C using malloc(), calloc(), free() and realloc()
- Difference Between malloc() and calloc() with Examples
- What is Memory Leak? How can we avoid?
- Dynamic Array in C
- How to dynamically allocate a 2D array in C?
- Dynamically Growing Array in C
- C/C++ Preprocessors
- C/C++ Preprocessor directives | Set 2
- How a Preprocessor works in C?
- Header Files in C/C++ and its uses
- What’s difference between header files “stdio.h” and “stdlib.h” ?
- How to write your own header file in C?
- Macros and its types in C/C++
- Interesting Facts about Macros and Preprocessors in C
- # and ## Operators in C
- How to print a variable name in C?
- Multiline macros in C
- Variable length arguments for Macros
- Branch prediction macros in GCC
- typedef versus #define in C
- Difference between #define and const in C?
- Basics of File Handling in C
- C fopen() function with Examples
- EOF, getc() and feof() in C
- fgets() and gets() in C language
- fseek() vs rewind() in C
- What is return type of getchar(), fgetc() and getc() ?
- Read/Write Structure From/to a File in C
- C Program to print contents of file
- C program to delete a file
- C Program to merge contents of two files into a third file
- What is the difference between printf, sprintf and fprintf?
- Difference between getc(), getchar(), getch() and getche()
- time.h header file in C with Examples
- Input-output system calls in C | Create, Open, Close, Read, Write
- Signals in C language
- Program error signals
- Socket Programming in C/C++
- _Generics Keyword in C
- Multithreading in C
- Top 50 C Programming Interview Questions and Answers
- Commonly Asked C Programming Interview Questions | Set 1
- Commonly Asked C Programming Interview Questions | Set 2
- Commonly Asked C Programming Interview Questions | Set 3
The conditional operator in C is kind of similar to the if-else statement as it follows the same algorithm as of if-else statement but the conditional operator takes less space and helps to write the if-else statements in the shortest way possible. It is also known as the ternary operator in C as it operates on three operands.
Syntax of Conditional/Ternary Operator in C
The conditional operator can be in the form
Or the syntax can also be in this form
Or syntax can also be in this form
Conditional/Ternary Operator in C
It can be visualized into an if-else statement as:
Since the Conditional Operator ‘?:’ takes three operands to work, hence they are also called ternary operators .
Note: The ternary operator have third most lowest precedence, so we need to use the expressions such that we can avoid errors due to improper operator precedence management.
Working of Conditional/Ternary Operator in C
The working of the conditional operator in C is as follows:
- Step 1: Expression1 is the condition to be evaluated.
- Step 2A: If the condition( Expression1 ) is True then Expression2 will be executed.
- Step 2B : If the condition( Expression1 ) is false then Expression3 will be executed.
- Step 3: Results will be returned.
Flowchart of Conditional/Ternary Operator in C
To understand the working better, we can analyze the flowchart of the conditional operator given below.
Flowchart of conditional/ternary operator in C
Examples of C Ternary Operator
Example 1: c program to store the greatest of the two numbers using the ternary operator, example 2: c program to check whether a year is a leap year using ternary operator.
The conditional operator or ternary operator in C is generally used when we need a short conditional code such as assigning value to a variable based on the condition. It can be used in bigger conditions but it will make the program very complex and unreadable.
FAQs on Conditional/Ternary Operators in C
1. what is the ternary operator in c.
The ternary operator in C is a conditional operator that works on three operands. It works similarly to the if-else statement and executes the code based on the specified condition. It is also called conditional Operator
2. What is the advantage of the conditional operator?
It reduces the line of code when the condition and statements are small.
Please Login to comment...
Improve your coding skills with practice.
C operator precedence.
The following table lists the precedence and associativity of C operators. Operators are listed top to bottom, in descending precedence.
- ↑ The operand of prefix ++ and -- can't be a type cast. This rule grammatically forbids some expressions that would be semantically invalid anyway. Some compilers ignore this rule and detect the invalidity semantically.
- ↑ The operand of sizeof can't be a type cast: the expression sizeof ( int ) * p is unambiguously interpreted as ( sizeof ( int ) ) * p , but not sizeof ( ( int ) * p ) .
- ↑ The expression in the middle of the conditional operator (between ? and : ) is parsed as if parenthesized: its precedence relative to ?: is ignored.
- ↑ Assignment operators' left operands must be unary (level-2 non-cast) expressions. This rule grammatically forbids some expressions that would be semantically invalid anyway. Many compilers ignore this rule and detect the invalidity semantically. For example, e = a < d ? a ++ : a = d is an expression that cannot be parsed because of this rule. However, many compilers ignore this rule and parse it as e = ( ( ( a < d ) ? ( a ++ ) : a ) = d ) , and then give an error because it is semantically invalid.
When parsing an expression, an operator which is listed on some row will be bound tighter (as if by parentheses) to its arguments than any operator that is listed on a row further below it. For example, the expression * p ++ is parsed as * ( p ++ ) , and not as ( * p ) ++ .
Operators that are in the same cell (there may be several rows of operators listed in a cell) are evaluated with the same precedence, in the given direction. For example, the expression a = b = c is parsed as a = ( b = c ) , and not as ( a = b ) = c because of right-to-left associativity.
[ edit ] Notes
Precedence and associativity are independent from order of evaluation .
The standard itself doesn't specify precedence levels. They are derived from the grammar.
In C++, the conditional operator has the same precedence as assignment operators, and prefix ++ and -- and assignment operators don't have the restrictions about their operands.
Associativity specification is redundant for unary operators and is only shown for completeness: unary prefix operators always associate right-to-left ( sizeof ++* p is sizeof ( ++ ( * p ) ) ) and unary postfix operators always associate left-to-right ( a [ 1 ] [ 2 ] ++ is ( ( a [ 1 ] ) [ 2 ] ) ++ ). Note that the associativity is meaningful for member access operators, even though they are grouped with unary postfix operators: a. b ++ is parsed ( a. b ) ++ and not a. ( b ++ ) .
[ edit ] References
- C17 standard (ISO/IEC 9899:2018):
- A.2.1 Expressions
- C11 standard (ISO/IEC 9899:2011):
- C99 standard (ISO/IEC 9899:1999):
- C89/C90 standard (ISO/IEC 9899:1990):
- A.1.2.1 Expressions
[ edit ] See also
Order of evaluation of operator arguments at run time.
- Recent changes
- Offline version
- What links here
- Related changes
- Upload file
- Special pages
- Printable version
- Permanent link
- Page information
- In other languages
- This page was last modified on 31 July 2023, at 10:28.
- This page has been accessed 2,489,223 times.
- About cppreference.com