Why this doesn't work on C but works on C++?
(0) ? a = 1 : a = 2;
The languages have differences in operator precedence.
In C++, the ternary operator has the same precedence as assignment operators, with the note
The expression in the middle of the conditional operator (between ? and :) is parsed as if parenthesized: its precedence relative to ?: is ignored.
In C, the ternary operator has higher precedence than assignment. It also has a the same note about the middle expression.
What this means is that in C, the expression is parsed as if it were parenthesized:
((0) ? (a = 1) : a) = 2;
which is invalid because the conditional expression doesn't return an L-value.
Related
We know ++ and - - can be prefix or postfix and it depends on the position of the operand. for example :
++a prefix because the operand is on the right of the operator.
a++ postfix because the operand is on the left of the operator.
But In complicated expressions things become confusing. for example :
! - -a == ++ ! b I know to solve this i must apply the precedence rule but that depend on how i will consider the type of ++ , a postfix or prefix.
My question how can i decide if an operator a postfix or a prefix and more generaly how can i determine the operand of an unary operator ?
Don't.
Making some assumptions about type, your code should be:
!(-(-a)) == ++(!b)
Note the use of parentheses to obviate the need to even think about precedence.
Except this isn't a valid expression, because you can't increment an rvalue/temporary (assuming you aren't overloading operator! and returning a reference, which would be non-idiomatic and weird).
Also each side of the == should be split off into a variable declaration for clarity.
const bool isItHot = !a;
const bool isItCold = !b; // ignoring your ++ for now
return (isItHot == isItCold);
If you really need a tool to work out the precedence for you, Geordi can do it, or you can work it out from some documentation.
In dart we have plenty of ternary operators.
But do we have one ternary operator just for if condition?
Example
In condition
if (num == 1){
print(true);
} else {
print(false);
}
In ternary
print(num == 1 ? true : false);
So do we have any ternary operator just for true condition like above example?
if (num == 1) {
print(true);
}
No.
The conditional operator ?/: in Dart requires all three operands.
It does so because all expressions must have a value, and if you could do just e1 ? e2, then the expression has no value if e1 is false.
It's not impossible to conceive of a binary conditional operator where the missing expression defaults to null, say (e1?:elseExpression) or (e1?thenExpression:), but then you can also just write the null, and saving four letters is probably not worth the potential loss of readability.
Ob-nitpick. The conditional operator in Dart is one of two ternary operators (operators requiring three operands, like binary operators require two operands), the other ternary operator being []=.
I wonder, since && is short-circuiting, we can use:
b && f(args) to replace if(b){ f(args);}
Where if b is true, function f will be executed. The drawback is that f must return a bool. A true() wrapper function could be used.
Hello guys after going through href=http://en.cppreference.com/w/c/language/operator_precedence this link ,
I thought I understood the operator precedence but I came to followings doubt.
The link says that 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)++.
So how does the expression ++*p gets evaluated is it like ++(*p) but if yes ++ has higher priority or bound then *, Then why does * is bound tighter in the above case, and what about the expression *++p ?
Operator precedence defines which operator should be applied first when there is more than one choice.
From your link:
Precedence and associativity are independent from order of evaluation.
The expression ++*p, or any expression of the form:
{operator 2} {operator 1} {expression}
has a well-defined order of evaluation, where {operator 1} {expression} must be applied in order to make an expression that {operator 2} may act on.
Yes ++ has higher precedence over * and the associativity for both is from right to left.
So
++*p will be evaluated as ++(*p) because ++ need to be applied on a modifiable value.
Whereas
*++p as you see when this is evaluated the operator close to p is ++ as well as have higher precedence over * so ++p will happen first followed by dereferencing *(++p)
Consider the following codes:
int a = 3;
int b = 0;
b = a > 0 ? ++b, ++a : --a, b = 0;
After execution, I get the value of b to become 0 and the value of a to become 4.
That means the result of condition expression, a > 0 is evaluated as true and the expression a++ has been executed, while the expression b = 0 after , hast been executed ,too. In other words, the expression b = 0 is not an operand of the ternary operator, while ++b is. Otherwise, b = 0 won't be executed since the condition expression isn't evaluated as false.
My question is "according to what rule does the compiler kick b = 0 out of the ternary operator's operand?"
The operators in the third statement includes: ++ and --, which have the highest precedence, >, which has the second largest precedence, ? : and =, which have the third largest precedence and , with the lowest precedence. I know that operators with higher precedence should determine their operands earlier so that ++,--, and > are handled first. Then the statement is equivalently:
b = (a > 0) ? (++b), (++a) : (--a), b = 0;
Now, it's = and ?:'s turn to be handled. The associativity of = and ?: is right-to-left, so I consider the compiler will parse the statement from the right end.The first operator met is = and so b = 0 is grouped together. The second met operator is ,. Since it's precedence is lower then the current operators being analyzed, I assume the compiler will just skip it. Then the compiler met :, which is a part of ternary operator, so it keeps parsing.(Actually I don't know how the compiler can know that : is a part of ?: before parsing the whole ternary operator) Problem comes here. The next operator met by the compiler is , but the compiler haven't finished determining the operands of ?: yet. The , has lower priority than ?:. Theoretically it should be skipped; surprisingly, in practical test, the (++b) and (++a) have been concatenated by the , operator at this time and both are considered as the operand of ?:. That makes me confused. Why does the last , is ignored and doesn't included in the operand of ?: while the previous , in statement is kept in the operand of ternary operator?
May someone clarify the concepts of precedence and associativity with this example? I'm really confused about the executing result when first taking a sight of this piece of codes. I had thought that the expression b=0 is also a part of the ternary operator's operand; therefore b = 0 will only be executed if a > 0 is false.
Thanks in advance.
Precedence and associativity are different concepts, but technically the C and C++ standard specifies none. Instead they give the grammar rules to deduce the structure of the expression.
The relevant rules are:
conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression
expression:
assignment-expression
expression , assignment-expression
primary-expression:
( expression )
postfix-expression:
primary-expression
...
And so on...
The idea is that each type of expression can generate a composite expresion or another type of expression of lower precedence. You can only go up to the root expression by using parenthesis.
With that in mind, note that the conditional-expression that uses the ?: actually has different types of expressions in each of the three subexpressions. The middle one is expression so it will accept any kind of expression, even with , or = (no ambiguity here because of the ending :).
But note that the last one is assignment-expression, that is any kind of expression except the one with ,. If you want to use that, you will have to enclose it with () creating a primary-expression instead.
Bonus explanation: the first expression is logical-or-expression, and if you look carefully to the grammar you'll see that it excludes assignment operators, the conditional operator and the comma operator.
So your expression:
b = a > 0 ? ++b, ++a : --a, b = 0
Is actually a expression comma assignment-expression, where the first expression is b = a > 0 ? ++b, ++a : --a and the second assignment-expression is b = 0.
And so on...
Your expression is evaluated as (b = ((a > 0) ? (++b, ++a) : (--a))), (b = 0);.
As you say the ?: has higher precedence than the comma operator, so the b=0 does not belong to the ternary conditional. The difference for the left and the right part of the ternary operator is, that on the left side the compiler tries to evaluate the complete string ++b, ++a as an expression (knowing that the part between ? and : must be an expression, while on the right side the compiler tries to parse an expression as far as it can. And precedence of operators says the compiler must stop at the ,. On the left side the compiler does not stop on the , because this is a legal part of the expression.
This question already has answers here:
What's the precedence of comma operator inside conditional operator in C++?
(3 answers)
Closed 9 years ago.
Well, I had a question about comma in ternary operator.
Cut the crap, the code is below:
void test_comma_in_condition(void)
{
int ia, ib, ic;
ia = ib = ic = 0;
bool condition=true;
cout<<"Original:"<<endl;
cout<<"ia: "<<ia<<endl;
cout<<"ib: "<<ib<<endl;
condition?(ia=1, ib=2):(ia=11, ib=12);
cout<<"After:"<<endl;
cout<<"ia: "<<ia<<endl;
cout<<"ib: "<<ib<<endl;
ia = ib = ic = 0;
condition?ia=1, ib=2, ic=3:ib=22,ia=21, ic=23;
cout<<"The operation must be bracketed, or you'll see..."<<endl;
cout<<"ia: "<<ia<<endl;
cout<<"ib: "<<ib<<endl;
cout<<"ic: "<<ic<<endl;
condition?ia=1, ib=2, ic=3:ia=21, ib=22, ic=23;
cout<<"The operation must be bracketed, or you'll see..."<<endl;
cout<<"ia: "<<ia<<endl;
cout<<"ib: "<<ib<<endl;
cout<<"ic: "<<ic<<endl;
return;
}
The output will be like:
Original:
ia: 0
ib: 0
After:
ia: 1
ib: 2
The operation must be bracketed, or you'll see...
ia: 21
ib: 2
ic: 23
The operation must be bracketed, or you'll see...
ia: 1
ib: 22
ic: 23
Is this legal?
This is a matter of operator precedence. Your expression:
condition?ia=1, ib=2, ic=3:ib=22,ia=21, ic=23;
is understood by the compiler as:
(condition?(ia=1, ib=2, ic=3):(ib=22)),ia=21, ic=23;
At this point you should be able to see why you get the program output.
Yes, the relevant grammar for a conditional expression is:
logical-or-expression ? expression : assignment-expression
for assignment expressions (which can also be a conditional-expression or a throw-expression):
logical-or-expression assignment-operator assignment-expression
and for an expression with a comma operator (an assignment-expression can also be an expression):
expression , assignment-expression
This means that the construct a ? b : c, d cannot be parsed as equivalent to a ? b : (c, d) because c, d is not an assignment-expression but must be parsed as equivalent to (a ? b : c), d.
There is no undefined behaviour in condition ? ia=1,ib=2,ic=3 : ia=21, ib=22, ic=23; because evaluation of condition is sequenced before the evaluation of either the second or third operands of ?: and in every sub-expression containing a comma operator the evaluation of the first operand of the comma operator is sequenced before the evaluation of the second operand.
It's legal, but stupid not very useful to write code like that.
The code
condition?ia=1, ib=2, ic=3:ia=21, ib=22, ic=23;
is equivalent to
condition?(ia=1, ib=2, ic=3):ia=21;
ib=22;
ic=23;
just harder to read.
The problem is that the comma operator has the lowest precedence there is. Thanks to that, the else part of the conditional operator is just the first assignment, after that the comma operator kicks in and the other two statements will be executed just aswell.