=+ operator in c++? - c++

I have a question on a program that includes the following if statement:
if (x =+ 4){
x += 5;
}
I've never seen anything like that before, surely it isn't a typo? Does =+ actually do anything?

x =+ 4
means
x= (+4)
or simply
x=4
though such construction syntactically correct and can be compiled, does not make much sense and most probably a typo, where x==4 was intended, especially that it is used as condition for if

In the early days of C, =+ was the same as +=, but that's long gone and never made its way into C++.
=+a is understood to be = (+a)
The unary + operator promotes the argument to an int if it's of a narrower type, otherwise it's a no-op.
And = is regular assignment.
You can contrive a difference between =+ and = in this way:
If = was twice overloaded for two particular pairings, for example {Foo, int} and {Foo, char}, and you had an instance of Foo foo and a char c, then
foo = c // calls the overload taking a `char`
and
foo =+ c // calls the overload taking an `int`
would call different overloads.

Sorry, my initial answer was due to foolishly misreading the question.
The correct answer, is this code simply assigns x the value of positive 4,
because this is then non zero it satisfies the if and increments it further by 5.
A simpler form of this program in its current state would be:
x = 9;
However I strongly suspect there was a typo involved and the statement inside the if condition should either be x == 4, x += 4 or x != 4 depending on context.

OK just to round this out, I did find that my hunch was right, =+ and =- are indeed just obsolete forms of the += and -= op's in use today:
Stack Overflow: What does =+ mean in C?
https://www.cs.auckland.ac.nz/references/unix/digital/AQTLTBTE/DOCU_064.HTM (now that's a vintage web page!)
and specifically
https://en.wikipedia.org/wiki/C_(programming_language)#K.26R_C
tells us that they were changed: "Compound assignment operators of the form =op (such as =-) were changed to the form op= (that is, -=) to remove the semantic ambiguity created by constructs such as i=-10, which had been interpreted as i =- 10 (decrement i by 10) instead of the possibly intended i = -10 (let i be -10)."
So it's not to do with making an argument explicitly +ve or -ve. You can simply substitute the modern forms, eg use += in place of =+.

Related

why i = ++i + 2 is undefined behavior? [duplicate]

This question already has answers here:
New Sequence Points in C++11
(2 answers)
So why is i = ++i + 1 well-defined in C++11?
(3 answers)
Closed 4 years ago.
I've read something about order of evaluation and I understand some mistakes caused by order of evaluation.
My basic rule comes from a text and example:
Order of operand evaluation is independent of precedence and associativity.
In most cases, the order is largely unspecified.
So for expression like this: int i = f1() * f2();
f1 and f2 must be called before the multiplication can be done. After all, it is their results that are multiplied. However, we have no way of knowing whether f1 will be called before f2 or vice versa.
Undefined behavior examples:
int i = 0;
cout << i << " " << ++i << endl;
How I understand: I treat i and ++i as a function. I don't know which evaluates first, so the first i could be 0 or 1 and (the rule) makes sense.
while(beg != s.end())
*beg = toupper(*beg++); //Just another example.
I think the key to understand this is to treat each operand as a "evaluation unit", and one don't know order of evaluation within these units but can know order in every single unit.
But for i = ++i + 2 reference here, Why is it wrong? I can't explain with my own conclusion.
The left i is used as a lvalue and not a pointer. ++i simply rewrite the original value and doesn't change the storage address. What could be wrong if it evaluates first or latter? My rule fails here.
Quite long but try to provide enough background info, thank for your patience.
I don't know sequence point which is mentioned frequently in answers.. So I think I need to read something about it first. Btw, the debate is not very helpful, for a newbie simply want to know why is it considered wrong, like before C++11?
I find this answer Undefined behavior and sequence points explain well why i = ++i + 2 is undefined behaviour before C++11
C++11 has new sequencing rules. In particular, for a pre-increment (++i) the side effect (writing the new value) is sequenced-before the further use of the new, incremented value. Since the assignment i= is sequenced-after the evaluation of its right-hand side, this means the write ++i is transitively sequenced-before the write i=(++i + 2)
It would be another matter for i=(i++ + 2). For post-increment, the side effect is sequenced-after, which means the two assignments are no longer sequenced relatively to each other. That IS undefined behavior.
Your two "subfunctions" in i = ++i + 2 are an explicit assignment made by the = operator and an implicit assignment done by the ++ operator.
The preincrement operator is defined to return an incremented value of the variable, and this definitely shall be used for addition (performed by the + operator). However, it was not defined, when the incremented value should be stored back into i.
As a result, it was undefined whether the final value of i is old_i incremented plus 2 or just old_i incremented.

C - What does x+1 means without assignment?

My question is maybe very simple, but I'm wondering what does this x+1 means?
Let's see an example:
int main()
{
int x = 2;
x + 1; //1
if ((x - 2) && (x = 7)) { //2 and 3
// do something
}
}
What i know:
That the assignment cannot be evaluated because left side of && will return false, so the conjunction will never be true.
Questions:
How does the memory looks like after operation 1?
Is the value of x changed after x-2 (2)?
I saw in debugger that this doesn't change the value of x, but I'm using a C++ compiler in Visual Studio so it can give another values.
Thanks in advance :)
The code
x+1;
evaluates the expression and then just drops the results. It's legal but a good compiler should issue a warning (IIRC g++ emits something about an expression that would require side effects to be useful).
The code (x - 2) && (x = 7) instead doesn't do anything, because && is "short-circuited" and x-2 is false in a logical context. So the code (x = 7) is not evaluated. && and || evaluate the left side first and the right side is evaluated only if the result cannot be determined from it... for example (1 || foo()) is guaranteed to skip the call to function foo.
Code like
y = (x - 2) * (x = 7);
would instead be undefined behavior because C++ is not required to work through sub-expressions in sequence (except for the comma operator ,, logical AND &&, logical OR|| and the ternary operator ?:) and using and modifying the same value in different parts of an expression (if these parts don't have a prescribed evaluation sequence) is not permitted but the compilers are not required to complain about it. Whatever happens happens, and it's a programmer's fault.
How does the memory looks like after operation 1?
It's the same as before the operation. x - 1 is an expression without side-effects (i.e. it doesn't modify any variable). The statement x - 1; evaluates the expression and discards the result. Any decent compiler will optimize it away.
To increment x by 1 you should use the compound assignment operator +=:
x += 1;
The same can be achieved with the increment operator ++:
x++; // these do the same
++x; // thing in this case
In other contexts, the two different versions of ++ have different meaning, see What is the difference between prefix and postfix operators?.
Is the value of x changed after x-2 (2)?
x - 2 itself doesn't change the value of x. (Again x -= 2 can be used to achieve that.)
However the assignment x = 7 changes the value of x to 7, if the assignment is evaluated (which happens if the left-hand-side of && evaluates to true or non-zero (this is called short-circuit evaluation). In this case the left-hand-side evaluates to zero so x = 7 is not evaluated).
Note that the = operator is different to the equality comparison operator ==:
x == 7 // evaluates to `true` if the value of `x` is equal to `7`, and to `false` otherwise.
It means "perform this calculation and throw away the result".
In your case that means the compiler will probably just remove the code completely (since it obviously has no side effects). But if operator+ had been overloaded and/or user-defined types had been involved, then there could be meaningful side-effects and the code could be meaningfull and would be kept to perform those operations..
x + 1 does not change value of x. The result of x + 1 viz 3 is calculated and the result is then ignored.
For and (&&) sequence of evaluation is left to right. As long as the components of && operator are true, the next component is evaluated.
As stated earlier for x + 1, similarly, x + 2 does not change value of x. In your case, x - 2 results into 0 viz. zero and so the next component is not evaluated.
The basic principles of C language, remain same across all compilers and IDE (in your case Visual Studio) has no effect on the compilation

C - Multiple assignments to same variable in one line

I came across this code line in C:
#define RUNDE(n) ( K ^= Q[n], y = K, K = F(K) ^ xR, xR = y )
Is it valid to assign something to K multiple times? I thought it's invalid to change a variable more than one time in one statement.
Is it valid to assign something to K multiple times?
That's perfectly valid C macro. A comma operator , is used here.
Using , operator you can assign a value to a variable multiple times.
e.g.K = 20, K = 30; This will assign 30 to K overwriting the previous value of 20.
I thought it's invalid to change a variable more than one time in one statement.
Yes it leads to undefined behavior if we try to modify a variable more than once in a same C statement but here first , is a sequence point.
So it's guaranteed that we will be modifying the K second time (K = 30) only when all the side effects of first assignment (K = 20) have taken place.
This is well-defined as the comma operator evaluates its first operand before its second.
However, IMHO this code is horrible and you shouldn't write it. inline functions exist to do things like this; using the preprocessor is just abuse. Sure, you would need to pass some arguments to an inline function, but this is far preferable to relying on names from the surrounding scope.
In C++ this would be regarded as nasty; in C it's permissible as the reliance on the preprocessor is more necessary.
But in either case your expression is perfectly well-defined. The comma operator (which is evaluated from left to right), acts as a sequenced expression separator.
The elegant thing with this macro is that its value is the value of xR = y, which is the final value of y.
But the inelegance of this macro, such as using variable names that are not passed as arguments, probably outweighs any benefits. My inclination is to bin it.
It is a valid comma operator, that perform all statements in sequence, returning the value of the last statement.
That macro is a sequence of assignments, using the last assignment (y or xR) as return value

Can someone explain this C/C++ syntax?

Can sombody explain how this works?
int x, y;
....
(some_condition ? x : y) = 100;
Is this intended to work or is is just a "blind" translation or the compiler (something like vec[10] equals 10[vec])?
This is valid C++ and invalid C.
The result of a conditional expression can be (and in this case is) an lvalue in C++ refering to one of x or y depending on whether some_condition evaluates to true. In C++ either x is assigned the value 100 if some_condition is true when converted to a bool, otherwise y is assigned 100.
In C, the result of a conditional expression is never an lvalue and cannot be assigned to.
At least in C++, that code snippet is essentially equivalent to this:
if(some_condition)
{
x = 100;
}
else
{
y = 100;
}
It is guaranteed by the C++ standard, although you have to read the relevant sections carefully. The rules of the operator are surprisingly complicated (mainly due to the type conversions that are performed) so the conditional operator and the if-then-else statement are not exactly equivalent all the time.
However, in your code snippet above, this paragraph in the standard is relevant:
5.16/4 Conditional operator:
If the second and third operands are lvalues and have the same type, the result is of that type and is an lvalue.
It is an expression which has the same result as this code:
if (some_condition)
x = 100;
else
y = 100;
if x and y are l-value, the ternary expression is an l-value.
Discussed here
No, it is a short form for a if condition. It is like
if(somecondition)
{
x = 100;
}
else
{
y = 100;
}
x and y are both lvalue of the same type.
I do not think that there is something blind in this code.
But you may find some compiler that cannot compile this code.
I usually prefer use if/else code which produce exactly the same code and is far more readable for maintainers.
And if you want to track bug it easier to put each branch on separate branch it is easier to set break points.
Code coverage control is also easier to check.
you assign to either x or y depending on the condition.
It looks like a ternary operator selecting an lvalue. I didn't know that could be done, but I suppose it rather makes sense. Based on the condition, one of the two values (x or y) will be assigned the number 100.
Very cool if it works!
It is intended to work.
The ternary operator ?: can produce an lvalue (i.e. something you can assign to) if both of its possible results are lvalues, as they are in your example.
So your example assigns a value to either x or y depending on some other value.
The value of x or y being replaced with 100 depends on the condition. It is also generally used while returning -
return condition ? x : y ; // If condition is true => return x else return y

Increment and Decrement operators

How are the below valid and invalid as shown and what do they mean. When would such a situation arise to write this piece of code.
++x = 5; // legal
--x = 5; // legal
x++ = 5; // illegal
x-- = 5; // illegal
The postfix (x++/x--) operators do not return an lvalue (a value you can assign into).
They return a temporary value which is a copy of the value of the variable before the change
The value is an rvalue, so you could write:
y = x++ and get the old value of x
Given that both operator=() and operator++() can be overloaded, it is impossible to say what the code does without knowing more about the type of thing the operators are being applied to.
Those all modify the value of x more than once between sequence points, and are therefore undefined behavior, which you should carefully avoid. I don't see where the distinction between "legal" and "illegal" comes in - since the behavior is legal, any behavior (including sending assorted email to the Secretary of State) is perfectly in accordance with the Standard.
Assuming that the question is about built-in ++ and -- operators, none of these statements are strictly legal.
The first two are well-formed, i.e. they merely compilable because the result of prefix increment is lvalue. The last two are ill-formed, since the result of postfix increment is not a rvalue, which is why you can't assign to it.
However, even the first two are not legal in a sense that they produce undefined behavior. It is illegal to modify the same object more than once without an intervening sequence point. (Note also, that compilers are allowed to refuse to compile well-formed code that produces undefined behavior, meaning that even the first pair might prove to be non-compilable).
++x and --x both give you back x (after it's been incremented/decremented). At that point you can do what you want with it, including assign it a new value.
x++ and x-- both give you back what x was (just before it was incremented/decremented). Altering this value makes no more sense than changing any ordinary function's return value:
obj->getValue() += 3; // pointless
Frankly, you should never write that. Postincrement and pre-increment (and decrements) should only ever be used on their own. They're just recipes for confusion.
The only place I can think of where such a situation would occur is with an operator overload of operator++ and operator=. Even then, the definition isn't clear. What you code is saying basically is add one to x, then assign 5 to it. A question would arise such as why would you need to increment x before assigning 5 to it? The only possible explanation is if you have some sort of class where the ++ operator somehow increment an internal counter, then the assignment. No idea why such a thing is needed though.