ternary and assignment operator precedence - c++

On MSVC v9.0, if I do this:
int myvalue;
myvalue = true ? 1 : 0;
then it seems that ?: is evaluated before '='. Is this a guarantee? I am using this table as a reference:
http://en.cppreference.com/w/cpp/language/operator_precedence
However, both operators are in the same row, so I'm not sure if they are evaluated in the order I expect or if this is guaranteed by the standard. Can anyone clarify this?

In this statement
int myvalue = true ? 1 : 0;
there's only one operator, the ternary operator. There's no assignment operator here, so precedence doesn't matter.
Don't confuse initialization with assignment:
int myvalue;
myvalue = true ? 1 : 0; // now priorities are important

From your link:
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.
Since both = and ?: are in the same cell and have right-to-left associativity, the ternary is guaranteed to evaluate first.

They are evaluated right to left, as it written in the table you linked. It is equivalent of this:
int myvalue = (true ? 1 : 0);

Right-to-left:
int myValue1 = 20, myValue2 = 30;
myValue1 = true ? 1 : 0; // which is the same as:
myValue1 = ((true) ? (1) : (0));
// myValue == 1 && myValue2 == 30
true ? myValue1 : myValue2 = 5; // which is the same as:
(true) ? (myValue1) : ((myValue2) = (5));
// myValue == 1 && myValue2 == 30
false ? myValue1 : myValue2 = 5; // which is the same as:
(false) ? (myValue1) : ((myValue2) = (5));
// myValue == 1 && myValue2 == 5
This is guaranteed in the C++ language

Related

Strange behaviour in C++ when comparing 2 values with "or" and "?" operator

I have some code in an old desktop app, which I inheritted from a colegue who left the company.
Here is a short similar example of the actual code I have:
#include <iostream>
int getType(int type)
{
return type;
}
int main()
{
int variable1 = 30;
int variable2 = 40;
int result = (getType(30) == (variable1 || variable2) ? 1 : 2);
std::cout << result << std::endl;
}
For the result I always receive 2, not 1 as I expected.
If I try:
int result = (getType(30) == (variable1) ? 1 : 2)
the result is true.
I can't figure out why this part:
int result = (getType(30) == (variable1 || variable2) ? 1 : 2)
is not true...
In the initializer expression of this declaration
int result = (getType(30) == (variable1 || variable2) ? 1 : 2);
the subexpression (variable1 || variable2) has the type bool and its value is true (variable1 isn't 0 so that is true) that is implicitly converted to the integer value 1 in the expression with the equality operator (getType(30) == (variable1 || variable2) .
From the C++17 Standard (7.6 Integral promotions)
6 A prvalue of type bool can be converted to a prvalue of type int,
with false becoming zero and true becoming one.
So as getType(30) is not equal to 1 the result of the initializer expression is 2.
To get the expected result you should rewrite the declaration like
int result = (getType(30) == variable1 || getType(30) == variable2) ? 1 : 2;
I think perhaps your understanding of the || operator is not quite right. The || operator is the or operator, and it will return a boolean result, false or true. In your code, you are doing this comparison: getType(30) == (variable1 || variable2). The parenthesis get evaluated first because of order of operations and you end up with getType(30) == true, since variable1 has a non-zero value. getType(30) evaluates and returns 30, so the expression is 30 == true. The true value then gets coerced to a 1 because of the rules of c++ and we evalate 30 == 1 which is false.
I think what you are asking for is why this doesn't do what you expect. And I see two problems, the one is that the getType function doesn't actually do what you might expect, it simply returns the variable. I'm not sure what you would expect in c++, but that's definitely a problem. The other expectation is probably that you want to compare the return of getType(30) with both variable1 and variable2 which would require a longer expression. The expression you want is probably getType(30) == variable1 || getType(30) == variable2. This is a common problem because in english we say 'if gettype equals var1 or var2`, but it doesn't translate into code like that unfortunately.

Variable changes on it's own in C++

I have a loop going through an array trying to find which index is a string. It should solve for what that value should be.
I can't figure out why, but as soon as the if statements start i becomes 1 which gives my code an error.
I'm not very fluent in C++.
for(int i = 0; i < 4; i++) {
if(auto value = std::get_if<std::string>(&varArr[i])) {
solvedIndex = i;
auto value0 = std::get_if<float>(&varArr[0]);
auto value1 = std::get_if<float>(&varArr[1]);
auto value2 = std::get_if<float>(&varArr[2]);
auto value3 = std::get_if<float>(&varArr[3]);
//i changes to 1 when this if starts??
if(i = 0) {
solvedVar = (*value3 / *value1) * *value2;
} else if (i = 1) {
solvedVar = *value3 / (*value0 / *value2);
} else if (i = 2) {
solvedVar = *value0 / (*value3 / *value1);
} else {
solvedVar = *value1 * (*value0 / *value2);
}
break;
}
}
Note that these variables are declared above. Also, varArr is filled with values:
std::variant<std::string, float> varArr[4];
int solvedIndex;
float solvedVar;
As has been noted, in your if statements, you are using the assignment operator (=) but want the equality comparison operator (==). For your variable i the first if statement sets i equal to 0 and if(0) is the same as if(false). So your program goes to the first else-if which sets i equal to 1 and if(1) evaluates to true. Your code then finishes the block within else if (i = 1) {...} and then ends.
That's because operator= is the assignment operator in C++ (and most languages, actually). That changes the value of the variable to the value on the other side. So, for instance:
x = 0
will change the value of x to 0. Doesn't matter if it's in an if statement. It will always change the value to 0 (or whatever the right hand side value is).
What you are looking for is operator==, which is the comparison (aka relational) operator in C++/ That asks the question "Are these two things equal?" So, for instance:
x == 0
asks is x is equal to 0.

I need to know the explanation of this sentence in c++ " b = (c > 5) ? a/c/2 : 0; "

I need to know the explanation of this sentence in C++
I am editing a library for BL0937 where it uses energy monitoring paramteres , I have just used a b c for simplicity
b = (c > 5) ? a/c/2 : 0;
That can be rewritten as
if(c>5)
{
b = (a/c)/2;
}
else
{
b = 0;
}
x ? y : z is a ternary operator that means "if x, then y, otherwise z."
a/c/2 is just a simple chain of division. As the division operator (/) evaluates from left to right, it is equivalent to (a/c)/2.
So your expression first evaluates c>5 and if that is true, it will evaluate to a/c/2, and otherwise 0. The evaluated value (either a/c/2 or 0) will be assigned to the variable b.
I'll mention more rules of operator precedence for c++, in case that you might be confused of the precedence of / and x ? y : z.
Here is an official page for operator precedence: https://en.cppreference.com/w/cpp/language/operator_precedence
From this, you know operator / has much priority to x ? y : z and =, and thus it is firstly calculated from left to right, i.e. a/c/2 equals (a/c)/2. And then x ? y : z has the same precedence as =, calculated from right to left. Now it means:
b = ( (c>5) ? ((a/c)/2) : 0 );
Hope it helps.

What is the meaning of A += B == 1

I have came across one type of usage of operator =. It was something like this:
A += B == 1;
where A and B are integers and this kind of usage I found in a function body.
I just kind of confused with the second == usage.
Of course I know the meaning of A = B = 1;
Can anybody explain me?
This code:
A += B == 1;
is logically equal to:
bool b = B == 1;
A += b;
Note: bool can be implicitly converted to int (true to 1 and false to 0)
== has higher precedence over +=, so it's executed first
B == 1 is a boolean expression, can be false or true
let's call that bool 'result'.
A += result is an addition + assignment (like A = A + result as you may already know).
Since A is an int in your case, the boolean result is implicitly converted to the number 1 if true, or 0 if false. (it would work similarily for other number types as well)
More on implicit conversions here : http://en.cppreference.com/w/cpp/language/implicit_conversion
So, at the end, this is logically equivalent to "increment A if and only if B is equal to 1" :
if (B == 1)
A += 1;

"DHT11 ? 0 : -40;" What does this syntax mean and what is it called?

return model == DHT11 ? 0 : -40;
I believe it means "return model if between 0 and -40", but I'd like a definitive answer.
Its the ternary operator, equivalent to:
if (model == DHT11)
return 0;
else
return -40;
so it has nothing to do with a check for a range.
The ternary operator yields a value, i.e. you could also use this in an assignment like:
retval = model == DHT11 ? 0 : 40;
return retval;
This operator (E1?E2:E3) is called ternary operator, where E are expressions.
It means : "If E1 is true, return E2, else, return E3"
Here's a link to cppreference explaning a bit more.
As already mentioned, it is called the ternary operator.
The ternary operator checks to see if something is true, and if it is, yields the value before the :. If it is false, it yields the value after the :.
In this situation, it checks to see if model == DHT11 evaluates to true, and gives 0 if so. If model == DHT11 evaluates to false, it gives -40. The value the ternary evaluates to is then given to return, quitting the function, and returning either 0 or -40.
Other example:
std::string hi = "hi";
std::cout << (hi == "hi") ? "string hi contains \"hi\"." : "string hi does not contain \"hi\"." << "\n";
Would print:
string hi contains "hi".
General Syntax:
bool ? value1 : value2
The ternary operator is just like an if-else statement, compacted down to one line.