According to microsoft, the operators in C++ are the same in visual studio C++ 2010
http://msdn.microsoft.com/en-us/library/x04xhy0h.aspx
However, look at the following builds:
int^ number = 32;
if (number < 100)
MessageBox::Show("The number is not greater than 100");
Build failed
'<' : 'System::Int32 ^' does not define this operator or a conversion to a type acceptable to the predefined operator
if (number <= 100)
MessageBox::Show("The number is not greater than 100");
Build failed
'<=' : 'System::Int32 ^' does not define this operator or a conversion to a type acceptable to the predefined operator
if (number == 32)
MessageBox::Show("The is equal to 32");
Build successful... However the message is not displayed.
if (number = 32)
MessageBox::Show("The is equal to 32");
Build successful.. The message is displayed. (Why? The operator of the equality is ==)
Why is this happening?
int^ declares a handle to an object. Whenever you reference number directly, you're actually referencing a boxed integer (somewhat equivalent to (object)32 in C#).
In addition, handles to objects don't define the < or <= (or > or >=) operators when comparing to an integer literal. The reason for that can be deducted from the following:
They do, however define an == operator. But in order to compare, the literal value you're comparing to will be implicitly boxed, making the comparison (somewhat) equivalent to this C# code:
object number = 32;
if (number == (object)32)
MessageBox.Show("The number is equal to 32");
That comparison will check if the references are the same. Which they aren't - they're two different objects. Hence:
int^ number = 32;
if (number == 32)
MessageBox::Show("The number is equal to 32"); // isn't displayed
... and since you're comparing references rather than values, >, >=, <=, < would make little sense.
In your last case, you're assigning 32 to number, then checking if the result of that expression (which is itself 32) is different from 0 - it is, so the message is displayed. That's what if does in C++ (and C) - in C#, number = 32 does have the result 32, but you'd get a compiler error due to the if requiring a boolean value.
"Solution": Dereference the int^:
if (*number == 32)
MessageBox::Show("The number is equal to 32");
... or simply use int:
int number = 32;
EDIT: Rewrote based on Ben Voigt's more correct explanation.
Related
What are "sequence points"?
What is the relation between undefined behaviour and sequence points?
I often use funny and convoluted expressions like a[++i] = i;, to make myself feel better. Why should I stop using them?
If you've read this, be sure to visit the follow-up question Undefined behavior and sequence points reloaded.
(Note: This is meant to be an entry to Stack Overflow's C++ FAQ. If you want to critique the idea of providing an FAQ in this form, then the posting on meta that started all this would be the place to do that. Answers to that question are monitored in the C++ chatroom, where the FAQ idea started out in the first place, so your answer is very likely to get read by those who came up with the idea.)
C++98 and C++03
This answer is for the older versions of the C++ standard. The C++11 and C++14 versions of the standard do not formally contain 'sequence points'; operations are 'sequenced before' or 'unsequenced' or 'indeterminately sequenced' instead. The net effect is essentially the same, but the terminology is different.
Disclaimer : Okay. This answer is a bit long. So have patience while reading it. If you already know these things, reading them again won't make you crazy.
Pre-requisites : An elementary knowledge of C++ Standard
What are Sequence Points?
The Standard says
At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations
shall be complete and no side effects of subsequent evaluations shall have taken place. (§1.9/7)
Side effects? What are side effects?
Evaluation of an expression produces something and if in addition there is a change in the state of the execution environment it is said that the expression (its evaluation) has some side effect(s).
For example:
int x = y++; //where y is also an int
In addition to the initialization operation the value of y gets changed due to the side effect of ++ operator.
So far so good. Moving on to sequence points. An alternation definition of seq-points given by the comp.lang.c author Steve Summit:
Sequence point is a point in time at which the dust has settled and all side effects which have been seen so far are guaranteed to be complete.
What are the common sequence points listed in the C++ Standard?
Those are:
at the end of the evaluation of full expression (§1.9/16) (A full-expression is an expression that is not a subexpression of another expression.)1
Example :
int a = 5; // ; is a sequence point here
in the evaluation of each of the following expressions after the evaluation of the first expression (§1.9/18) 2
a && b (§5.14)
a || b (§5.15)
a ? b : c (§5.16)
a , b (§5.18) (here a , b is a comma operator; in func(a,a++) , is not a comma operator, it's merely a separator between the arguments a and a++. Thus the behaviour is undefined in that case (if a is considered to be a primitive type))
at a function call (whether or not the function is inline), after the evaluation of all function arguments (if any) which
takes place before execution of any expressions or statements in the function body (§1.9/17).
1 : Note : the evaluation of a full-expression can include the evaluation of subexpressions that are not lexically
part of the full-expression. For example, subexpressions involved in evaluating default argument expressions (8.3.6) are considered to be created in the expression that calls the function, not the expression that defines the default argument
2 : The operators indicated are the built-in operators, as described in clause 5. When one of these operators is overloaded (clause 13) in a valid context, thus designating a user-defined operator function, the expression designates a function invocation and the operands form an argument list, without an implied sequence point between them.
What is Undefined Behaviour?
The Standard defines Undefined Behaviour in Section §1.3.12 as
behavior, such as might arise upon use of an erroneous program construct or erroneous data, for which this International Standard imposes no requirements 3.
Undefined behavior may also be expected when this
International Standard omits the description of any explicit definition of behavior.
3 : permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or with-
out the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
In short, undefined behaviour means anything can happen from daemons flying out of your nose to your girlfriend getting pregnant.
What is the relation between Undefined Behaviour and Sequence Points?
Before I get into that you must know the difference(s) between Undefined Behaviour, Unspecified Behaviour and Implementation Defined Behaviour.
You must also know that the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified.
For example:
int x = 5, y = 6;
int z = x++ + y++; //it is unspecified whether x++ or y++ will be evaluated first.
Another example here.
Now the Standard in §5/4 says
Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.
What does it mean?
Informally it means that between two sequence points a variable must not be modified more than once.
In an expression statement, the next sequence point is usually at the terminating semicolon, and the previous sequence point is at the end of the previous statement. An expression may also contain intermediate sequence points.
From the above sentence the following expressions invoke Undefined Behaviour:
i++ * ++i; // UB, i is modified more than once btw two SPs
i = ++i; // UB, same as above
++i = 2; // UB, same as above
i = ++i + 1; // UB, same as above
++++++i; // UB, parsed as (++(++(++i)))
i = (i, ++i, ++i); // UB, there's no SP between `++i` (right most) and assignment to `i` (`i` is modified more than once btw two SPs)
But the following expressions are fine:
i = (i, ++i, 1) + 1; // well defined (AFAIK)
i = (++i, i++, i); // well defined
int j = i;
j = (++i, i++, j*i); // well defined
Furthermore, the prior value shall be accessed only to determine the value to be stored.
What does it mean? It means if an object is written to within a full expression, any and all accesses to it within the same expression must be directly involved in the computation of the value to be written.
For example in i = i + 1 all the access of i (in L.H.S and in R.H.S) are directly involved in computation of the value to be written. So it is fine.
This rule effectively constrains legal expressions to those in which the accesses demonstrably precede the modification.
Example 1:
std::printf("%d %d", i,++i); // invokes Undefined Behaviour because of Rule no 2
Example 2:
a[i] = i++ // or a[++i] = i or a[i++] = ++i etc
is disallowed because one of the accesses of i (the one in a[i]) has nothing to do with the value which ends up being stored in i (which happens over in i++), and so there's no good way to define--either for our understanding or the compiler's--whether the access should take place before or after the incremented value is stored. So the behaviour is undefined.
Example 3 :
int x = i + i++ ;// Similar to above
Follow up answer for C++11 here.
This is a follow up to my previous answer and contains C++11 related material..
Pre-requisites : An elementary knowledge of Relations (Mathematics).
Is it true that there are no Sequence Points in C++11?
Yes! This is very true.
Sequence Points have been replaced by Sequenced Before and Sequenced After (and Unsequenced and Indeterminately Sequenced) relations in C++11.
What exactly is this 'Sequenced before' thing?
Sequenced Before(§1.9/13) is a relation which is:
Asymmetric
Transitive
between evaluations executed by a single thread and induces a strict partial order1
Formally it means given any two evaluations(See below) A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. If A is not sequenced before B and B is not sequenced before A, then A and B are unsequenced 2.
Evaluations A and B are indeterminately sequenced when either A is sequenced before B or B is sequenced before A, but it is unspecified which3.
[NOTES]
1 : A strict partial order is a binary relation "<" over a set P which is asymmetric, and transitive, i.e., for all a, b, and c in P, we have that:
........(i). if a < b then ¬ (b < a) (asymmetry);
........(ii). if a < b and b < c then a < c (transitivity).
2 : The execution of unsequenced evaluations can overlap.
3 : Indeterminately sequenced evaluations cannot overlap, but either could be executed first.
What is the meaning of the word 'evaluation' in context of C++11?
In C++11, evaluation of an expression (or a sub-expression) in general includes:
value computations (including determining the identity of an object for glvalue evaluation and fetching a value previously assigned to an object for prvalue evaluation) and
initiation of side effects.
Now (§1.9/14) says:
Every value computation and side effect associated with a full-expression is sequenced before every value computation and side effect associated with the next full-expression to be evaluated.
Trivial example:
int x;
x = 10;
++x;
Value computation and side effect associated with ++x is sequenced after the value computation and side effect of x = 10;
So there must be some relation between Undefined Behaviour and the above-mentioned things, right?
Yes! Right.
In (§1.9/15) it has been mentioned that
Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced4.
For example :
int main()
{
int num = 19 ;
num = (num << 3) + (num >> 3);
}
Evaluation of operands of + operator are unsequenced relative to each other.
Evaluation of operands of << and >> operators are unsequenced relative to each other.
4: In an expression that is evaluated more than once during the execution
of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations.
(§1.9/15)
The value computations of the operands of an
operator are sequenced before the value computation of the result of the operator.
That means in x + y the value computation of x and y are sequenced before the value computation of (x + y).
More importantly
(§1.9/15) If a side effect on a scalar object is unsequenced relative to either
(a) another side effect on the same scalar object
or
(b) a value computation using the value of the same scalar object.
the behaviour is undefined.
Examples:
int i = 5, v[10] = { };
void f(int, int);
i = i++ * ++i; // Undefined Behaviour
i = ++i + i++; // Undefined Behaviour
i = ++i + ++i; // Undefined Behaviour
i = v[i++]; // Undefined Behaviour
i = v[++i]: // Well-defined Behavior
i = i++ + 1; // Undefined Behaviour
i = ++i + 1; // Well-defined Behaviour
++++i; // Well-defined Behaviour
f(i = -1, i = -1); // Undefined Behaviour (see below)
When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function. [Note: Value computations and side effects associated with different argument expressions are unsequenced. — end note]
Expressions (5), (7) and (8) do not invoke undefined behaviour. Check out the following answers for a more detailed explanation.
Multiple preincrement operations on a variable in C++0x
Unsequenced Value Computations
Final Note :
If you find any flaw in the post please leave a comment. Power-users (With rep >20000) please do not hesitate to edit the post for correcting typos and other mistakes.
C++17 (N4659) includes a proposal Refining Expression Evaluation Order for Idiomatic C++
which defines a stricter order of expression evaluation.
In particular, the following sentence
8.18 Assignment and compound assignment operators:....
In all cases, the assignment is sequenced after the value
computation of the right and left operands, and before the value computation of the assignment expression.
The right operand is sequenced before the left operand.
together with the following clarification
An expression X is said to be sequenced before an expression Y if every
value computation and every side effect associated with the expression X is sequenced before every value
computation and every side effect associated with the expression Y.
make several cases of previously undefined behavior valid, including the one in question:
a[++i] = i;
However several other similar cases still lead to undefined behavior.
In N4140:
i = i++ + 1; // the behavior is undefined
But in N4659
i = i++ + 1; // the value of i is incremented
i = i++ + i; // the behavior is undefined
Of course, using a C++17 compliant compiler does not necessarily mean that one should start writing such expressions.
I am guessing there is a fundamental reason for the change, it isn't merely cosmetic to make the old interpretation clearer: that reason is concurrency. Unspecified order of elaboration is merely selection of one of several possible serial orderings, this is quite different to before and after orderings, because if there is no specified ordering, concurrent evaluation is possible: not so with the old rules. For example in:
f (a,b)
previously either a then b, or, b then a. Now, a and b can be evaluated with instructions interleaved or even on different cores.
In C99(ISO/IEC 9899:TC3) which seems absent from this discussion thus far the following steteents are made regarding order of evaluaiton.
[...]the order of evaluation of subexpressions and the order in which
side effects take place are both unspecified. (Section 6.5 pp 67)
The order of evaluation of the operands is unspecified. If an attempt
is made to modify the result of an assignment operator or to access it
after the next sequence point, the behavior[sic] is undefined.(Section
6.5.16 pp 91)
When comparing objects it's common that you will end up with an integer other than -1, 0, 1.
e.g. (in Java)
Byte a = 10;
Byte b = 20;
System.out.println(a.compareTo(b)); // -10
Is there any algorithm, data-structure used in practice that takes advantage of this attribute of the comparison model?
Or in other words: why is any number > 1 or < -1 is a helpful piece of info?
Edit: I'm sorry. I see how you could've misinterpreted the question as a Java problem. My mistake. I changed the tag from "java" to "language agnostic".
The contract of a Comparable object specifies that the value returned by compareTo() is:
A negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
The above definition simplifies comparisons, we just need to test the returned value against zero using the usual comparison operators. For instance, to check if object a is greater than or equal to object b we can write:
a.compareTo(b) >= 0
Also, this is more flexible than simply returning -1, 1 or 0 as it allows each implementation to return a value with additional information. For example, String's compareTo() returns:
The difference of the two character values at position k in the two strings -- that is, the value:
this.charAt(k) - anotherString.charAt(k)
If there is no index position at which they differ, then the shorter string lexicographically precedes the longer string. In this case, compareTo returns the difference of the lengths of the strings -- that is, the value:
this.length() - anotherString.length()
No algorithm will take advantage of this "attribute", because you cannot rely on the exact value returned.
The only guarantee you have, is that it will be <0, =0, or >0, because that is the contract defined by Comparable.compareTo():
Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
The Byte implementation isn't any more specific:
Returns the value 0 if this Byte is equal to the argument Byte; a value less than 0 if this Byte is numerically less than the argument Byte; and a value greater than 0 if this Byte is numerically greater than the argument Byte (signed comparison).
Anything else is arbitrary and may change without notice.
To clarify, the returned value is defined to be <0, =0, or >0 instead of -1, 0, or +1 as a convenience to the implementation, not as a means to provide additional information to the caller.
As an example, the Byte.compareTo(Byte anotherByte) is implemented to return a number between -255 and 255 (inclusive) with this simple code:
return this.value - anotherByte.value;
The alternative would be code like:
return this.value < anotherByte.value ? -1 : this.value > anotherByte.value ? 1 : 0;
Since it's as easy for the caller to test the return value x < 0 instead of x == -1, allowing the broader range of return values provides for cleaner, more optimal code.
In a few code examples, I've seen algorithms to check if a bit is set such as in the following:
for (int i = 0; i < 32; i++)
{
// count number of elements with i'th bit set
int count = 0;
for (int j = 0; j < n; j++)
if ( (arr[j] & (1 << i)) ) // array holds integers
count++;
where the if statement checks to see if the current number in the array has the ith bit turned on. For example, if the number in the current index of the array is 4 (0100 in 4-bit representation) and i is 2 (corresponding to the 3rd bit), the AND operation would be
0100
0100 &
= 0100
which returns a 4. Since if statements check for truth values (values of 1 or 0) how would it interpret that AND operation to be true for cases like the one just described?
If this example compiles, you are very likely doing it in C, C++, or Objective-C (as opposed to Java or C#, where this example wouldn't compile).
Both C and C++ have a rule that interprets zeros as false and all non-zeros as true in contexts where logical expression is expected. Imagine that an implicit != 0 is appended to numeric expressions in contexts where a logical expression is expected.
if statement requires a logical expression, so any non-zero value is considered true. That is why this implementation works.
To build on the other answers, this is actually stated in the C++11 standard.
4.12 Boolean conversions [conv.bool]
1 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. A prvalue of type std::nullptr_t can be converted to a prvalue of
type bool; the resulting value is false.
My current method of comparing two reals (after calculations) is to take the difference and cast to an integer and compare to 0, for example (just to highlight the problem, example might work in simulator)
variable a : real := 0.1;
constant epsilon : real := 1.0E-5; -- Whatever accuracy needed, not too low though
a := a + 5.3;
assert a = 5.4; -- Yields intermitent errors
assert integer(a - 5.4) = '0'; -- Erroneous if 4.8 < a < 5.9 due to cast rounding
assert abs(a - 5.4) < epsilon; -- Will work everytime, but seems a bit forced
The reason for this way is that I got a lot of assertion errors in an testbench I wrote (a tad more complext then the example code). I was accounting these errors as floating point errors in GHDL simulator. Is there a better way to compare two reals to each other, like using machine epsilon, or any build in methods?
As indicated by #Philippe, comparison of reals requires some margin to account for limited precision and accumulated errors in the least significant bits. Using a simple epsilon value is one common way to do this but it has a limitation in that its value is absolute in relation to the numbers being compared. You need to know in advance the expected values you're comparing to pick a suitable epsilon.
If the set of numbers you need to compare covers a wide range of magnitudes you end up with an epsilon that is too large for properly comparing small values. In this situation you'd want a small epsilon when comparing small reals and a larger epsilon for larger numbers. This is accomplished by using a comparison that accounts for relative error.
This page gives a good overview of a method that allows comparison of reals using relative error rather than absolute error. The following function is an implementation of the relative comparison in VHDL:
-- Adapted from: http://floating-point-gui.de/errors/comparison/
function relatively_equal(a, b, epsilon : real) return boolean is
begin
if a = b then -- Take care of infinities
return true;
elsif a * b = 0.0 then -- Either a or b is zero
return abs(a - b) < epsilon ** 2;
else -- Relative error
return abs(a - b) / (abs(a) + abs(b)) < epsilon;
end if;
end function;
Here the epsilon parameter is a fraction that specifies the number of significant digits to compare for relative equality.
-- Compare for relative equality to three significant digits
-- These are all considered equal while using the same epsilon parameter
assert relatively_equal(1.001, 1.002, 1.0E-3) report "1.001 != 1.002";
assert relatively_equal(100.1, 100.2, 1.0E-3) report "100.1 != 100.2";
assert relatively_equal(1001.0, 1002.0, 1.0E-3) report "1001 != 1002";
-- Compare for relative equality to four significant digits
-- This will raise the assertion
assert relatively_equal(1.001, 1.002, 1.0E-4) report "1.001 != 1.002";
This question is generic to any programming language that uses "real" values (a.k.a. floating point numbers).
The standard way to compare reals in automatic tests is to define an small value epsilon. Then check that the absolute difference between your two reals is less than epsilon. You can define your own procedure assertEqual(x,y, epsilon) if you want to write concise test benches.
procedure assertEquals(
x, y : real; epsilon : real := 1.0E-5;
message : string := "";
level : severity_level := error) is
begin
assert (abs (x - y) < epsilon) report message severity level;
end procedure assertEquals;
This article talks about the optimization of code and discusses Instruction level parallelism. They give an example of GPU vector math where the float4 vector math can be performed on the vector rather than the individual scalars. Example given:
float4 x_neighbor = center.xyxy + float4(-1.0f, 0.0f, 1.0f, 0.0f);
Now my question is can it be used for comparison purposes as well? So in the reduction example, can I do this:
accumulator.xyz = (accumulator.xyz < element.xyz) ? accumulator.xyz : element.xyz;
Thank you.
As already stated by Austin comparison operators apply on vectors as well.
The point d. in the section 6.3 of the standard is the relevant part for you. It says:
The relational operators greater than (>), less than (<), greater than
or equal (>=), and less than or equal (<=) operate on scalar and
vector types.
it explains as well the valid cases:
The two operands are scalars. (...)
One operand is a scalar, and the other is a vector. (...) The scalar type is then widened to a vector that has the same number of
components as the vector operand. The operation is done component-wise
resulting in the same size vector.
The two operands are vectors of the same type. In this case, the operation is done component-wise resulting in the same size vector.
And finally, what these comparison operators return:
The result is a scalar signed integer of type int if the source
operands are scalar and a vector signed integer type of the same size
as the source operands if the source operands are vector types.
For scalar types, the relational operators shall return 0 if the
specified relation is false and 1 if the specified relation is true.
For vector types, the relational operators shall return 0 if the
specified relation is false and –1 (i.e. all bits set) if the
specified relation is true. The relational operators always return 0
if either argument is not a number (NaN).
EDIT:
To complete a bit the return value part, especially after #redrum's comment; It seems odd at first that the true value is -1 for the vector types. However, since OCL behaves as much as possible like C, it doesn't make a big change since everything that is different than 0 is true.
As an example is you have the vector:
int2 vect = (int2)(0, -1);
This statement will evaluate to true and do something:
if(vect.y){
//Do something
}
Now, note that this isn't valid (not related to the value returned, but only to the fact it is a vector):
if(vect){
//do something
}
This won't compile, however, you can use the function all and any to evaluate all elements of a vector in an "if statement":
if(any(vect){
//this will evaluate to true in our example
}
Note that the returned value is (from the quick reference card):
int any (Ti x): 1 if MSB in component of x is set; else 0
So any negative number will do.
But still, why not keep 1 as the returned value when evaluated to true?
I think that the important part is the fact that all bits are set. My guess, would be that like that you can make easily bitwise operation on vectors, like say you want to eliminate the elements smaller than a given value. Thanks to the fact that the value "true" is -1, i.e. 111111...111, you can do something like that:
int4 vect = (int4)(75, 3, 42, 105);
int ref = 50;
int4 result = (vect < ref) & vect;
and result's elements will be: 0, 3, 42, 0
in the other hand if the returned value was 1 for true, the result would be: 0, 1, 0, 0
The OpenCL 1.2 Reference Card from Khronos says that logical operators:
Operators [6.3]
These operators behave similarly as in C99 except that
operands may include vector types when possible:
+ - * % / -- ++ == != &
~ ^ > < >= <= | ! && ||
?: >> << = , op= sizeof