I once seen a -wired- operator in C++ which assigns value if greater than..
it was a combination of ?, < and =
e.g. let x = value if value is greater than x
I do not mean x=(x<value)x:value
It was some sort of x<?=value
But I can not remember it exactly, and can not find it online... Can some one remind me of it?
Thanks,
There is no operator that assigns variables based on their relative values.
However, there is the ?: operator:
x = value > x ? value : x;
If you read it out loud from left to right, it makes sense.
gcc has -- in version 3.3.6 at least! -- a gcc-specific language extension providing specialized operators for implementing min and max. Perhaps this is what you are thinking of?
Minimum and Maximum Operators in C++
I don't have gcc handy to test it with, but it might have an updating form, too.
How's that:
(x<value) || (x=value)
Are you thinking of the ternary operator?
result = a > b ? x : y;
I suspect what you're thinking of is a gcc extension1 that lets you leave out the middle operand to the conditional operator, so (for example):
a = b ? b : c;
can be written as:
a = b ?: c;
1 Despite the '2.95.3' in the URL, I'm not aware of a newer version of the linked page. If somebody is, please feel free to point it out (or edit it in).
it's a more convenient version of an if statement that is used for assignment
int x = (some bool) ? trueval : falseval;
this is roughly what it means, when the bool is evaluated it either gets the trueval or falseval depending on the outcome, it's easier than saying
int x;
if (someval)
x = trueval;
else
x = falseval;
x = x < value ? 0 : 1;
This function sets x to 0 is x < value, 1 otherwise.
Related
I have recently noticed an strange valid C/C++ expression in GCC/Clang which I have never seen before. Here is the example in C++, but similar expression works in C too:
int main(){
int z = 5;
auto x = ({z > 3 ? 3 : 2;}); // <-- expression
std::cout << x;
}
What it does is somehow obvious, but I like to know what it is called. Since it does not worth in MSVC, I guess it is a non-standard extension. But is there anything that works for MSVC too? especially in C?
It's called statement expr, used in GCC. Your expression ({z > 3 ? 3 : 2;}) can be translated to
if (z > 3) {x = 3;} else {x = 2;}
From documentation:
A compound statement enclosed in parentheses may appear as an
expression in GNU C. This allows you to use loops, switches, and local
variables within an expression.
In other word, it provides the ability to put a compound statement in an expression position.
Related post :
Emulating GCC Statement Expressions
Use of ({ ... }) brackets in macros to swallow the semicolon
It is called conditional operator . Return will be depend on condition either condition is true or false.
But in this case:
auto x = ({z > 3 ? 3 : 2;}); // <-- expression
if Z is greater than 3 returns 3 otherwise 2.
Basic syntax : Expression1? expression2: expression3;
int x = 5,y = 10;
bool boolean = 0;
int k = (boolean ? ++x, ++y : --x, --y);
cout<<k;
When boolean is 0,it outputs 9, however when it is 1 it outputs 10.I know this is happening because of precedence but cannot exactly figure out how is it happening, please help me understand this.
NOTE:I know I can get the expected output if I use parenthesis,or better write a clean code,I am just using this to understand how compiler would evaluate expressions like these according to precedence.
, has lower precedence than ?:. Which means that the full parenthesising is:
int k = ((boolean ? (++x, ++y) : --x), --y);
As you can see, k is always initialised to the value of --y. It's just that if boolean is true, ++y happens before that.
When looking for the full parenthesis form of an expression, think of it as constructing the expression tree (where the lowest-precedence operator is at the root).
Find the lowest-precedence operator in an expression, and parenthesise its left-hand side argument and its right-hand side argument. Repeat recursively within the sub-expressions just parenthesised.
Due to the comma operator having the lowest operator precedence, your statement is actually equal to
k = (boolean ? (++x, ++y) : --x), --y;
That means when boolean is true you both increase and decrease y. The result of the ternary expression is thrown away in both cases and k is only assigned the result of --y.
It should be noted that this is not undefined behavior, as the comma operator introduces a sequence point.
To get the result you expect, you need to do
k = boolean ? (++x, ++y) : (--x, --y);
Note that the parentheses around ++x, ++y is strictly not needed, but it does make the expression clearer.
Given the above excellent answers, one should write instead:
if (boolean) {
++x;
++y;
} else {
--x;
--y;
}
int k = y;
Because then the code is more readable and clear in its intent. This will help anyone who has to maintain the code (including the original author!) without anyone having to waste time by asking SO questions or worrying about the precedence of , or ?: or what the logistics of assignment to such a complex expression are. Any modern compiler will optimize both this and the above to the same resulting code
Consider the following snippets:
C++:
#include <iostream>
using namespace std;
int main()
{
int x = 10, y = 20;
y = x + (x=y)*0;
cout << y;
return 0;
}
which gives a result of 20, because the value of y is assigned to x since the bracket is executed first according to the Operator Precedence Table.
VB.NET:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim x As Integer = 10
Dim y As Integer = 20
y = x + (x = y) * 0
MsgBox(y)
End Sub
which instead gives a result of 10.
What is the reason for this difference?
What is the order of execution of operators in VB.NET?
Unlike in C++, VB.NET's = is not always an assignment. It can also be the equality comparison operator (== in C++) if it appears inside an expression. Therefore your two expressions are not the same. They are not even equivalent. The VB.NET code does not do what you might think it does.
First to your C++ code: Like you're saying, the assignment x=y happens first; thus your code is roughly equivalent to this: (It seems that was incorrect; see Jens' answer.) Since you end up with y being 20, it is likely that your C++ compiler evaluated your code as if you had written this:
int x = 10, y = 20;
x = y;
y = x + x*0; // which is equivalent to `y = 20 + 20*0;`, or `y = 20 + 0;`, or `y = 20;`
In VB.NET however, because the = in your subexpression (x=y) is not actually interpreted as an assignment, but as a comparison, the code is equivalent to this:
Dim x As Integer = 10
Dim y As Integer = 20
y = 10 + False*0 ' which is equivalent to `y = 10 + 0*0`, or `y = 10` '
Here, operator precedence doesn't even come into play, but an implicit type conversion of the boolean value False to numeric 0.
(Just in case you were wondering: In VB.NET, assignment inside an expression is impossible. Assignments must always be full statements of their own, they cannot happen "inline". Otherwise it would be impossible to tell whether a = inside an expression meant assignment or comparison, since the same operator is used for both.)
Your C++ snippet is undefined behavior. There is no sequence point between using x as the first argument and assigning y to x, so the compiler can evaluate the sub-expressions in any order. Both
First evaluate the left side: y = 10 + (x=y) * 0 -> y = 10 + (x=20) * 0 -> y = 10 + 20*0
First evaluate the right side: y = x + (x=20) * 0 -> y = 20 + 20 * 0
It is also generally a very bad style to put assignments inside expressions.
This answer was intended as a comment, but its length quickly exceeded the limit. Sorry :)
You are confusing operator precedence with evaluation order. (This is a very common phenomenon, so don't feel bad). Let me try to explain with a simpler example involving more familiar operators:
If you have an expression like a + b * c then yes, the multiplication will always happen before the addition, because the * operator binds tighter than + operator. So far so good? The important point is that C++ is allowed to evaluate the operands a, b and c in any order it pleases. If one of those operands has a side effect which affects another operand, this is bad for two reasons:
It may cause undefined behavior (which in your code is indeed the case), and more importantly
It is guaranteed to give future readers of your code serious headaches. So please don't do it!
By the way, Java will always evaluate a first, then b, then c, "despite" the fact that multiplication happens before addition. The pseudo-bytecode will look like push a; push b; push c; mul; add;
(You did not ask about Java, but I wanted to mention Java to give an example where evaluating a is not only feasible, but guaranteed by the language specification. C# behaves the same way here.)
I am aware of two techniques for flipping a bool:
x = !x
and
x ^= 1
I prefer the second, in the same way that I prefer x++ over x+=1 over x=x+1.
But are they guaranteed to produce the same Assembly code?
And if not, is there some rationale to favour one over the other?
There are never any guarantees about same assembly code. Yes, given bool x, they both do exactly the same thing. Yes, that implies they are likely to be the same.
It is a common fallacy that writing expressions in an unusual way might make them faster. Avoid working with anyone who makes habits based on such ideas.
x = ! x is clearer because ! is defined in terms of Boolean values.
I prefer the second, in the same way that I prefer x++ over x+=1 over x=x+1.
Please prefer the first. It is expected and easily understood by most programmers. The second form, only works for values 0 and 1 in integer's case.
But are they guaranteed to produce the same Assembly code?
No.
And if not, is there some rationale to favour one over the other?
Decreasing the ratio of "wtf/loc" of you code (i.e. how many times would another developer look at your code and say "WTF?!?", over every n lines of code).
Edit: Either way, you will probably never see a real-world example of an application made faster by replacing one expression with the other. It is a matter of style, not a matter of performance.
The second expression is simply a source of difficulty found bugs. For example you may think that some expression has type bool while its actual type due to the integer promotion or usual arithmetic conversion is some integral type.
Consider the following code snippet
unsigned int x = 3;
x ^= 1;
std::cout << x << std::endl;
if ( x == false ) std::cout << "All is O'k\n";
else std::cout << "Oops. Something is wrong!\n";
x = 3;
x = !x;
std::cout << x << std::endl;
if ( x == false ) std::cout << "All is O'k\n";
else std::cout << "Oops. Something is wrong!\n";
So using expression x ^= 1; to flip a boolean value can only confuse readers of the code.
So I would prefer to use x = !x; instead of x ^= 1;
Do not forget about the principle KISS: Keep It Simple Stupid.:)
Though for example in C the result of operator ! has type int nevertheless the value of the operation is either 0 or 1.
From the C Standard
5 The result of the logical negation operator ! is 0 if the value of
its operand compares unequal to 0, 1 if the value of its operand
compares equal to 0.
So for both languages there is a guarantee that the result will be exactly either 0 or 1 for any source value.
!x and x^1 are clearly different operations.
The former is a logical negation, returning a 0/1 value. It makes sense to use it on bools.
The latter is a bitwise exclusive or, returning any possible value. It shouldn't be used on a bool. (For xoring bools, prefer the inequality comparison !=). It is also less efficient in unoptimized code as it invoves and extra operand (1).
K&R forgot to provide a !! operator, that you would have loved, and possibly ~~.
[This question is related to but not the same as this one.]
If I try to use values of certain types as boolean expressions, I get a warning. Rather than suppress the warning, I sometimes use the ternary operator (?:) to convert to a bool. Using two not operators (!!) seems to do the same thing.
Here's what I mean:
typedef long T; // similar warning with void * or double
T t = 0;
bool b = t; // performance warning: forcing 'long' value to 'bool'
b = t ? true : false; // ok
b = !!t; // any different?
So, does the double-not technique really do the same thing? Is it any more or less safe than the ternary technique? Is this technique equally safe with non-integral types (e.g., with void * or double for T)?
I'm not asking if !!t is good style. I am asking if it is semantically different than t ? true : false.
The argument of the ! operator and the first argument of the ternary operator are both implicitly converted to bool, so !! and ?: are IMO silly redundant decorations of the cast. I vote for
b = (t != 0);
No implicit conversions.
Alternatively, you can do this: bool b = (t != 0)
Careful!
A boolean is about truth and falseness.
An integer is about whole numbers.
Those are very distinct concepts:
Truth and falseness is about deciding stuff.
Numbers are about counting stuff.
When bridging those concepts, it should be done explicitly. I like Dima's version best:
b = (t != 0);
That code clearly says: Compare two numbers and store the truth-value in a boolean.
All valid techniques, all will generate the same code.
Personally, I just disable the warning so I can use the cleanest syntax. Casting to a bool is not something I'm worried about doing accidentally.
Yes it is safe.
0 is interpreted as false, everthing else is true,
hence !5 comes out as a false
!0 comes out as true
so !!5 comes out as true
I would not use:
bool b = !!t;
That is the least readable way (and thus the hardest to maintain)
The others depend on the situation.
If you are converting to use in a bool expression only.
bool b = t ? true : false;
if (b)
{
doSomething();
}
Then I would let the language do it for you:
if (t)
{
doSomething();
}
If you are actually storing a boolean value. Then first I would wonder why you have a long in the first places that requires the cast. Assuming you need the long and the bool value I would consider all the following depending on the situation.
bool b = t ? true : false; // Short and too the point.
// But not everybody groks this especially beginners.
bool b = (t != 0); // Gives the exact meaning of what you want to do.
bool b = static_cast<bool>(t); // Implies that t has no semantic meaning
// except as a bool in this context.
Summary:
Use what provides the most meaning for the context you are in.
Try and make it obvious what you are doing
I recommend never suppressing that warning, and never using a c cast (bool) to suppress it. The conversions may not always be called as you assume.
There is a difference between an expression that evaluates to true and a boolean of that value.
Both !! and ternary take getting used to, but will do the job similarly, if you do not want to define internal types with overloaded casts to bool.
Dima's approach is fine too, since it assigns the value of an expression to a bool.
If you're worried about the warning, you can also force the cast: bool b = (bool)t;
I really hate !!t!!!!!!. It smacks of the worst thing about C and C++, the temptation to be too clever by half with your syntax.
bool b(t != 0); // Is the best way IMHO, it explicitly shows what is happening.
Comparison to 0 doesn't work so well.
Which comes back -- why !! vs. ternary?
class foo { public: explicit operator bool () ; };
foo f;
auto a = f != 0; // invalid operands to binary expression ('foo' and 'int')
auto b = f ? true : false; // ok
auto c = !!f; // ok
!! may be compact, but I think it is unnecessarily complicated. Better to disable the warning or use the ternary operator, in my opinion.
I would use b = (0 != t) -- at least any sane person can read it easily. If I would see double dang in the code, I would be pretty much surprised.
Disable the warning.
Write for clarity first; then profile; then optimize for speed, where required.
!! is only useful when you're using a boolean expression in arithmetic fashion, e.g.:
c = 3 + !!extra; //3 or 4
(Whose style is a different discussion.) When all you need is a boolean expression, the !! is redundant. Writing
bool b = !!extra;
makes as much sense as:
if (!!extra) { ... }
I recommend to use
if (x != 0)
or
if (x != NULL)
instead of if(x); it's more understandable and readable.
The double not feels funny to me and in debug code will be very different than in optimized code.
If you're in love with !! you could always Macro it.
#define LONGTOBOOL(x) (!!(x))
(as an aside, the ternary operator is what I favor in these cases)
I would use bool b = t and leave the compile warning in, commenting on this particular line's safety. Disabling the warning may bite you in the butt in another part of the code.