Unary Operators Behavior

The behavior of unary & operator when met []

If the operand is the result of a unary * operator, neither that
operator nor the & operator is evaluated and the result is as if both
were omitted, except that the constraints on the operators still apply
and the result is not an lvalue.

Unary & applied to the result of unary *, cancels the * and converts the operand of the original * to an r-value:

#include <assert.h>
int main()
{
int *p=&(int){42};
assert(&*p == p); //the value (42) is not fetched from the target
#if 0
&*p = &(int){1000}; //not OK; & cancels the * but converts p to an r-value (can't be on the left-hand side of an assignment)
#endif
p = &(int){1000}; //ok; p is an l-value (can be on the left hand side of an assignment)
//(more accurately: can have its address taken)
}

Now since a pointerOrArray[index] expression is defined (6.5.2.1p2) as *(pointerOrArray+index) (the result of a unary *, except the * is hidden), you can apply the same rule to it: &pointerOrArray[index] <=> (pointerOrArry+Index). That's what your first quoted sentence says.

The last sentence you quoted can be (within the context of 6.5.3.2p3) interpreted as:

Otherwise (if unary & isn't combined with * or []), the result (of unary &) is a pointer to the object (&object) or function (&function) designated by its operand (an object or a function).

Unary operators behavior

I suspect you're seeing a side effect of the parser's behavior in how it interprets numeric literals.

If we create our own class:

class C
def +@
11
end
end

and then look at some things:

> c = C.new
> +c
=> 11
> ++c
=> 11

That's exactly what we expect to happen. If we use your Fixnum unary + override and a Fixnum variable:

> n = 23
> +n
=> 15
> ++n
=> 15

then again we see what you're expecting. In both cases, we see the result of calling the +@ method on a non-literal.

But when we look at +6 with your operator in place:

> +6
=> 6

the +@ method is not called. Similarly if we override -@:

class Fixnum
def -@
'pancakes'
end
end

and see what it does:

> -42
=> 42

So what's going on here? Well, Ruby is seeing +6 and -42 not as 6.send(:+@) and 42.send(:-@) method calls but as single literals for positive six and negative forty-two.

If you start adding parentheses, +(6) and -(42), then Ruby sees non-literal expressions and ends up calling the unary methods. Similarly when you double the unary operators.

unary operator in avr: undefined behavior?

voltage = voltage*2/3 multiplies voltage by 2, divides by 3, and stores the result in voltage.

voltage *= 2/3 divides 2 by 3, multiplies the result by voltage and stores the result of that in voltage. Integer division truncates, so 2/3 produces zero.

None of those are unary operators.

Atomic behavior of unary increment operators

Somewhere I read that unary operators are atomic by nature and so they can be used as it is in multi threaded environment.

That source is completely wrong. You need to use std::atomic (or the C equivalent) to achieve atomicity – unary operations are not special.


I compared the disassembly of both programs and found no difference

That doesn't mean that the generated operations are atomic. There is no difference as any decent compiler will optimize x=x+1 and ++x into the same assembly (assuming built-in types).

C: unary minus operator behavior with unsigned operands

Yes, 6.2.5c9 is exactly the paragraph that you looked for.

What's the significant use of unary plus and minus operators?

The Unary + operator converts its operand to Number type.
The Unary - operator converts its operand to Number type, and then negates it.
(per the ECMAScript spec)

In practice, Unary - is used for simply putting negative numbers in normal expressions, e.g.:

var x = y * -2.0;

That's the unary minus operator at work. The Unary + is equivalent to the Number() constructor called as a function, as implied by the spec.

I can only speculate on the history, but the unary +/- operators behave similarly in many C-derived languages. I suspect the Number() behavior is the addition to the language here.

Unary operators in java vs c++

In C++ the behavior of a statement such as i = i++ + ++i; is actually undefined so the fact that the behavior differs is not so surprising.

In fact it shouldn't be surprising if two different C++-compilers produce different behavior for the C++ statement i = i++ + ++i;.

Related question:

  • Why are these constructs (using ++) undefined behavior?
  • When exactly is the postfix increment operator evaluated in a complex expression?

Unary operators ++ and -- weird situation

This is an unintuitive (but not "weird"!) behaviour when using post-increment.

The statement j = j++ does this:

  1. Evaluate the LHS
    • In this case, nothing special happens because you simply named a variable, but this may not always be the case, e.g. foo() = j++
  2. Evaluate the RHS
    • Take the current value of j (0), and remember it as the result;
    • Increment j (to get 1);
  3. Assign the RHS to the LHS
    • recall that the RHS evaluates to that "remembered" value of j (0).

The result is a no-op.

The key here is that the entire RHS is evaluated and the post-increment performed, before the final assignment.


http://www.ecma-international.org/ecma-262/5.1/#sec-11.3.1
http://www.ecma-international.org/ecma-262/5.1/#sec-11.13.1

what is the output of conditional operator with unary operator

The expression on the right hand side is evaluated like an if-statement.

if (Delay == true)
return 1;
else
return -1;

The result is then used for the += assignment.

In the
C++20 draft standard that's

7.6.19 (6) (Assignment and compound assignment operators)

The behavior of an expression of the form E1 op= E2 is equivalent to E1 = E1 op E2 except that E1 is
evaluated only once. [...]

Since Delay == false, the return value of the ternary operator is -1. The fact that you're operating on a boolean instead of an int can make it look like you got the +1 back.

Note that you get a compiler warning C4804:

warning C4804: '+=': unsafe use of type 'bool' in operation

Is it undefined behavior? No.

7.6.19 (6) (Assignment and compound assignment operators)

[...] For += and
-=, E1 shall either have arithmetic type or be a pointer to a possibly cv-qualified completely-defined object
type. In all other cases, E1 shall have arithmetic type.

and

7.3.8 (2) (Integral conversions)

If the destination type is bool, see 7.3.14.

which says

7.3.14 (1) (Boolean conversions)

A prvalue of arithmetic, unscoped enumeration, pointer, or pointer-to-member type can be converted to a
prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false;
any other value is converted to true.

So the -1 is converted to true and true prints as 1.



Related Topics



Leave a reply



Submit