What is the "?" and ":" sequence actually called? [duplicate] - c++

This question already has answers here:
What does the question mark character ('?') mean in C++?
(8 answers)
Closed 9 years ago.
This may be a bonehead question, but I cannot figure out what the ? exp : other_exp sequence is called.
Example:
int result = (true) ? 1 : 0;
I've tried using the Google machine, but it's hard to Googilize for something without knowing what it's called.
Thanks!

It is called the the conditional operator or alternativly the ternary operator as it a ternary operator (an operator which takes 3 operands (arguments)), and as it's usually the only operator, that does this.
It is also know as the inline if (iif), the ternary if or the question-mark-operator.
It is actualy a rather useful feature, as they are expressions, rather than statements, and can therefore be used, for instance in constexpr functions, assigments and such.
The C++ Syntax is;
logical-or-expression ? expression : assignment-expression
It's used as;
condition ? condition_is_true_expression : condition_is_false_expression
That is, if condition evaluates to true, the expression evaluates to condition_is_true_expression otherwise the expression evaluates to condition_is_false_expression.
So in your case, result would always be assigned the value 1.
Note 1; A common mistake that one makes while working with the conditional operator, is to forget that it has a fairly low operator precedence.
Note 2; Some functional languages doesn't provide this operator, as they have expression 'if...else' constructs, such as OCaml;
let value = if b then 1 else 2
Note 3; A funny use case, which is perfectly valid is using the conditional operator, to decide, which of two variable to assign a value to.
(condition ? x : y) = 1;
Notice the parentheses are necessary, as this is really what you get without them;
condition ? x : (y = 1);

They are called shorthand if-else or ternary operators.
See this article for more information.

Related

Ternary operator, if I avoid writing ' expression 2 ' it works but if I not write 'expression 3 ' it gives an error [duplicate]

This question already has an answer here:
Ternary operator without the middle expression
(1 answer)
Closed 1 year ago.
Code
#include<iostream>
int main()
{
int a=4,b,c;
a==3 ? : b=a*a ; // Works fine
a==4 ? c=a*a : ; // ERROR Expected Primary expression before ;
}
1st conditional statement
I did not write 'Expression 2' but it will not produce error
2nd Conditional statement
I did not write 'Expression 3' it gives an error
so why it is differentiating in 'Expression 2' and 'Expression 3' ?
This is supported in GNU C/C++ and is called the Elvis operator. It's not allowed in standard C++ (e.g. MSVC++ doesn't support it).
It's described in the official documentation
6.8 Conditionals with Omitted Operands
The middle operand in a conditional expression may be omitted. Then if the first operand is nonzero, its value is the value of the conditional expression.
Therefore, the expression
x ? : y
has the value of x if that is nonzero; otherwise, the value of y.
This example is perfectly equivalent to
x ? x : y
In this simple case, the ability to omit the middle operand is not especially useful. When it becomes useful is when the first operand does, or may (if it is a macro argument), contain a side effect. Then repeating the operand in the middle would perform the side effect twice. Omitting the middle operand uses the value already computed without the undesirable effects of recomputing it.

Ternary operator in C vs C++ [duplicate]

This question already has answers here:
Errors using ternary operator in c
(5 answers)
Closed 8 years ago.
There are a lot of differences between C and C++ and came to stuck on one of them
The same code gives an error in C while just executes fine in C++
Please explain the reason
int main(void)
{
int a=10,b;
a>=5?b=100:b=200;
}
The above code gives an error in C stating lvalue required while the same code compiles fine in C++
Have a look at the operator precedence.
Without an explicit () your code behaves like
( a >= 5 ? b = 100 : b ) = 200;
The result of a ?: expression is not a modifiable lvalue [#] and hence we cannot assign any values to it.
Also, worthy to mention, as per the c syntax rule,
assignment is never allowed to appear on the right hand side of a conditional operator
Relared Reference : C precedence table.
OTOH, In case of c++, well,
the conditional operator has the same precedence as assignment.
and are grouped right-to-left, essentially making your code behave like
a >= 5 ? (b = 100) : ( b = 200 );
So, your code works fine in case of c++
[ # ] -- As per chapter 6.5.15, footnote (12), C99 standard,
A conditional expression does not yield an lvalue.
Because C and C++ aren't the same language, and you are ignoring the assignment implied by the ternary. I think you wanted
b = a>=5?100:200;
which should work in both C and C++.
In C you can fix it with placing the expression within Parentheses so that while evaluating the assignment becomes valid.
int main(void)
{
int a=10,b;
a>=5?(b=100):(b=200);
}
The error is because you don't care about the operator precedence and order of evaluation.

How does this work in c++? [duplicate]

This question already has answers here:
How does the Comma Operator work
(9 answers)
Closed 9 years ago.
I ran into a situation like this:
if(true,false)
{
cout<<"A";
}
else
{
cout<<"B";
}
Actually it writes out B. How does this statement works? Accordint to my observation always the last value counts. But then what is the point of this?
Thanks
from http://www.cplusplus.com/doc/tutorial/operators/
The comma operator (,) is used to separate two or more expressions
that are included where only one expression is expected. When the set
of expressions has to be evaluated for a value, only the right-most
expression is considered.
For example, the following code: a = (b=3, b+2);
would first assign the value 3 to b, and then assign b+2 to variable
a. So, at the end, variable a would contain the value 5 while variable
b would contain value 3.
So here
if(true,false)
{
}
evaluates to if(false)
According to http://www.cplusplus.com/doc/tutorial/operators/
The comma operator (,) is used to separate two or more expressions that are included where only one expression is expected. When the set of expressions has to be evaluated for a value, only the right-most expression is considered.
So for example consider the following:
int a, b;
a = (b=3, b+2);
b gets set to 3, but the equals operator only cares about the second half so the actual value returned is 5. As for the usefulness? That's conditional :)
The comma operator will run whatever is on the left side of the comma, discard it, and then run whatever is on the right side of the operator. In this case:
if (true, false)
will always be equivalent to if (false), so it will never run the if condition, and will always run the else condition.
As a side note: Never write code like this. It is serving no purpose but to obfuscate the code.

Why the Standard C++ Grammar for Assignment Expression Looks so Weird

From the C++ standard, the grammar for an assignment expression is like this:
assignment-expression:
conditional-expression
logical-or-expression assignment-operator assignment-expression
throw-expression
assignment-operator: one of
= *= /= %= += -= >>= <<= &= ^= |=
Notice that the left hand side of the "assignment-operator" is "logical-or-expression" i.e. something like (4 || localvar1) = 5; is a valid assignment expression according to the grammar. This doesn't make sense to me. Why they choose a "logical-or-expression" instead of, say, an identifier or id_expression?
The grammar is a bit complex, but if you continue unrolling with the previous definitions you will see that assignment expressions are very generic and allow for mostly anything. While the snippet from the standard that you quote focuses on logical-or-expression, if you keep unrolling the definition of that you will find that both the left hand side and right hand side of an assignment can be almost any subexpression (although not literally any).
The reason as pointed out before is that assignment can be applied to any lvalue expression of enum or fundamental type or rvalue expression of a class type (where operator= is always a member). Many expressions, in a language that allows for operator overloading and that does not define what the type returned from the operator is, can potentially fulfill the needs of assignment, and the grammar must allow all of those uses.
Different rules in the standard will later limit which of the possible expressions that can be generated from the grammar are actually valid or not.
Your particular statement, (4 || localvar1) = 5; is invalid (unless operator|| is overloaded), because you can't assign 5 to 4 (4 is an r-value). You must have an l-value (something that can be assigned to) on the left, such as a reference returned by a function.
For example, say you have some function int& get_my_int() that returns the reference to an integer. Then, you can do this:
`get_my_int() = 5;`
This will set the integer returned by get_my_int() to 5.
Just like in your first post, this MUST be a reference to an integer (and not a value); otherwise, the above statement wouldn't compile.
There are actually two interesting things about the C++ grammar for assignment statements, neither of which have to do with the validity of:
(4 || localvar1) = 5;
That expression is syntactically valid (up to type-checking) because of the parentheses. Any parenthesized expression of reference type is syntactically correct on the left-hand-side of an assignment operator. (And, as has been pointed out, almost any expression which involves a user type or function can be of reference type, as a result of operator overloading.)
What's more interesting about the grammar is that it establishes the left precedence of assignment operators as being lower than almost all other operators, including logical-or, so that the above expression is semantically equivalent to
4 || localvar1 = 5;
even though many readers would interpret the above as 4 || (localvar1 = 5) (which would have been totally correct assuming that localvar1 is of a type which can be assigned to by an int, even though said assignment will never happen -- unless, of course, || is overloaded in this context).
So what has a lower precedence on the left hand side of an assignment operator? As I said, very little, but one important exception is ?::
// Replace the larger of a and b with c
a > b ? a = c : b = c;
is valid and conveniently parenthesis-less. (Many style guides insist on redundant parentheses here, but I personally rather like the unparenthesized version.) This is not the same as right-hand precedence, so that the following also works without parentheses:
// Replace c with the larger of a and b
c = a > b ? a : b;
The only other operators which bind less tightly on the left of an assignment operator than the assignment operator are the , operator and another assignment operator. (In other words, assignment is right-associative unlike almost all other binary operators.) Neither of these are surprising -- in fact, they are so necessary that it's easy to miss how important it is to design a grammar in this way. Consider the following unremarkable for clause:
for (first = p = vec.begin(), last = vec.end(); p < last; ++p)
Here the , is a comma operator, and it clearly needs to bind less tightly than either of the assignments which surround it. (C and C++ are only exceptional in this syntax by having a comma operator; in most languages, , is not considered an operator.) Also, it would obviously be undesirable for the first assignment expression to be parsed as (first = p) = vec.begin().
The fact that assignment operators associate to the right is unremarkable, but it's worth noting for one historical curiosity. When Bjarne Stroustrup was looking around for operators to overload for I/O streams, he settled on << and >> because, although an assignment operator might have been more natural [1], assignment binds to the right, and a streaming operator must bind to the left (std::cout << a << b must be (std::cout << a) << b). However, since << binds much more tightly than assignment, there are a number of gotchas when using the streaming operators. (The one which most recently caught me is that shift binds more tightly than the bitwise operators.)
[Note 1]: I don't have a citation for this, but I remember reading it many years ago in The C++ Programming Language. As I recall, there was not a consensus about assignment operators being natural, but it seems more natural than overloading shift operators to be something completely different from their normal semantics.

syntactical use of comma operator in C++

I was going through someone elses code and I wasn't able to get the syntax of following
c = x<0 ? x = -x,'L':'R';
and
if(x) x--,putchar(c);
going by the symantics, it is clear that in the first, variable c is assigned 'L' or 'R'.And in the second, both x-- and putchar() are executed. But what exactly is the role of comma operator here??
But what exactly is the role of comma operator here?
In this case, code obfuscation. The original developer probably thought they were being clever.
The comma operator allows you to perform multiple actions in a single statement, but you are almost always better off using 2 statements. In those cases, it expands to:
if( x < 0 ) {
x = -x;
c = 'L';
} else {
c = 'R';
}
and
if(x) {
x--;
putchar(c);
}
The comma operator evaluates both expressions, and returns the value of the last.
The first expression does two things in one statement. If chooses 'L'
or 'R' and also sets x to its negative if 'L' is chosen.
The second expression (the part after the 'if') decrements x and then
puts a character. The meaning of this is unclear without more context.
Readability in both could be improved by using separate statements rather than the comma operator. The first tries to shoehorn an if statement into a conditional expression. But the second is already using an if statement, so it's unclear why the comma operator was chosen at all.
The role of the comma operator in that context is to allow using the conditional operator and write an assignment as part of the evaluation of one of the expressions.
In my opinion, this is just horrible style. An if statement would have better communicated the intent of that code, and would have hardly been less efficient.