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:
- 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++
- In this case, nothing special happens because you simply named a variable, but this may not always be the case, e.g.
- Evaluate the RHS
- Take the current value of
j
(0), and remember it as the result; - Increment
j
(to get 1);
- Take the current value of
- Assign the RHS to the LHS
- recall that the RHS evaluates to that "remembered" value of
j
(0).
- recall that the RHS evaluates to that "remembered" value of
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 toE1 = 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 bool
ean 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
Ruby: "If !Object.Nil" or "If Object"
How to Set a Proxy in Rubys Net/Http
Rails Is Not Using My Global Ruby Version
How to Upload a JSON File with Secret Keys to Heroku
No Such File to Load -- Bundler/Setup (Ruby on Rails)
Why #!/Usr/Bin/Env Ruby Doesn't Work in Crontab
Autoload Paths and Nested Services Classes Crash in Ruby
Upgrade Ruby on Elastic Beanstalk
What Is the Advantage of Creating an Enumerable Object Using To_Enum in Ruby
Behaviour of Array Bang Methods
How to Generate a Unique Request Id in Rails
Given a Url, How to Get Just the Domain
How to Make Rake Db:Migrate Generate Schema.Rb When Using :SQL Schema Format
Ruby: Automatically Set Instance Variable as Method Argument
Single Table Inheritance to Refer to a Child Class with Its Own Fields
Why Does the Rand() Return Always the Same Number