Suppose you have a C line of code &x->y->z (doesn't matter what the x/y/z's are). What is the order of evaluation here? I see that -> takes precedence over & in https://en.cppreference.com/w/c/language/operator_precedence. So is this evaluation sequence correct?
x->y is evaluated, and with that result
(x->y)->z is evaluated, and with that result
&((x->y)->z) is evaluated
If this is incorrect, can you tell me what the correct order is?
You are right this is the correct order. explination below:
&x->y->z
if we look in your expression above no matter what is x,y and z. we see that its contained from arrow -> operators or more technicaly speeking (Structure and union member access through pointer) and the address operator &.
In c programing there is the precedence and associativity for all operators. when we come to expression that we have 2 operators with the same precedence then we need to look at the associativity inorder to know what expression we need to evaluate first.
your expression have 2 -> operators and one & operator. -> operator is in the higest (precedence 1) precedence group of operators (he is not alone in this group see the table below). and & in the second higest group (precedence 2) and he is not alone in this group. so operator -> must be evaluated first. but where to start? here comes the associativity. for group 1 in the table below, we evaluates from left to right.
SO the order of the evaluation is:
x->y : evaluate first. for example lets assume its evaluates to P. (x->y=P)
P->z OR (x->y)->z: evaluates after the first (we are going from left to right folowing the associativity rule).
&((x->y)->z) : only now we evaluate the & operator and this will be the final result.
see the link below for C Operator Precedence
First of all, "precedence" doesn't mean order of evaluation . It refers to the association of operands with operators. For example in f() + g() * h(), the three function calls could occur in any order; saying that * has higher precedence is saying that the two operands of * are g() and h(). The compiler might call all three functions, and then multiply the results of the g and h calls, and then add the result of the f call.
In &x->y->z things are easier because the second operand of -> (and .) isn't an expression. It's an identifier that names a class member. So the second operand isn't evaluated, really.
The precedence rules, or grammar table, tells use that the operand of the unary & operator is x->y->z.
To understand x->y->z, clearly it is not the case that we are looking for a member of the struct pointed to by x whose name is "y->z" since that is not a valid identifier. That would not be a valid syntax parse. So it can only mean that ->z is applied to the result of x->y.
You are exactly correct.
The -> operator has the highest precedence and groups from left to right. So that gives you &((x->y)->z).
Related
So, I was looking at a C code, and saw this condition in a while loop:
while(x&&D(x-1),(x/=2)%2&&(1))
I searched but only found one with commands, and then condition, and not with two conditions.
',' operator in your context evaluates the first condition discards the result and then evaluates the second condition.
x&&D(x-1) this condition is evaluated but the result is not considered. Since in
(x/=2)%2&&(1) x value is used the changes made to 'x' in first condition are used in second condition but the truthfulness of first condition is not considered for your while loop.
(x/=2)%2&&(1), here (x/=2) is evaluated as x=x/2. And modulus(%) operator is applied on the result. so say your x value after evaluation of first condition is 11, then x/=2 evaluates x to 5 and then 5%2 is 1(gives reminder of 5/2).
&& is a logical AND operator. If left side of && is true then right side is evaluated. In the above example since left side is true(results to 1) and right side is already 1, your (x/=2)%2&&(1) evaluates to True.
I hope this answers your doubt. Remember with comma operator the left side condition/expression of comma is evaluated but its result is discarded.
you can find little insights to comma operator in below link.
https://www.geeksforgeeks.org/comna-in-c-and-c/
I have a class Download that serves as a wrapper for CKQueryOperation. One of the inits allows me to build my predicate with an array of values:
init(type: String, queryField: String, queryValues: [CKRecordValue], to rec: RecievesRecordable, from database: CKDatabase? = nil) {
let predicate = NSPredicate(format: "\(queryField) = %#", argumentArray: queryValues)
query = CKQuery(recordType: type, predicate: predicate)
reciever = rec
db = database
super.init()
}
When I test it, query only matches the first value in the array. So if queryValues = [testValue0, testValue1] and I have one record whose field matches testValue0 and I have a second record that matches testValue1, only the first record will be discovered. If I switch the order, than the other record gets recognized.
It seems weird that I can create a predicate with an array but only the first value gets matched. The documentation says that values are substituted in the order they appear, but shouldn't it still be moving on to the second value?
For more context, each record is stored in a separate database (private vs public) and my Download class launches two separate CKQueryOperations that both rely on query, if database param is left nil. Whichever op fails ends up finding no results that match the first value and then giving up before checking the second value.
I can include the full code for 'Download' and my failing unit test if needed.
You are using the wrong predicate. You want to use the IN operation. And instead of using string substitution for the field name, use the %K format specifier:
let predicate = NSPredicate(format: "%K IN %#", arguments: queryField, queryValues)
Note that the NSPredicate(format:argumentArray:) expects there to be one format specifier in the format string for each value in the argument array. Since your format only had one format specifier, only the first value was taken from the array. And since you used =, the field was simply compared against that one value.
Basic Comparisons
=, == The left-hand expression is equal to the right-hand expression.
=, => The left-hand expression is greater than or equal to the right-hand expression. <=, =< The left-hand expression is less than or
equal to the right-hand expression.
The left-hand expression is greater than the right-hand expression. < The left-hand expression is less than the right-hand expression. !=,
<> The left-hand expression is not equal to the right-hand expression.
String Comparisons
BEGINSWITH The left-hand expression begins with the right-hand
expression.
CONTAINS The left-hand expression contains the right-hand expression.
ENDSWITH The left-hand expression ends with the right-hand expression.
LIKE The left hand expression equals the right-hand expression: ? and
are allowed as wildcard characters, where ? matches 1 character and * matches 0 or more characters.
MATCHES The left hand expression equals the right hand expression
using a regex-style comparison according to ICU v3 (for more details
see the ICU User Guide for Regular Expressions).
I used Basic Comparisons
let resultPredicate = NSPredicate(format: "%K = %#", "key", "value")
let result_filtered = MYARRAY.filtered(using: resultPredicate) as NSArray
More information : Predicate Programming Guide
In C we often say that the operators are left-associative and right associative,
A left-associative operator is for example which starts from the left side and ends on the right of the user.
If for example in case of assignment operator x=y; for x=5 and y=20, is like saying put value of y in the x, that seems very legitimate.
but in cases like if(x>y), '>` operator has left associativity.
Means it computes Is x greater than y? FALSE.
But, why we go like this we can also say it reading from right associativity
Is y smaller than x? FALSE
Why use left associativity when the output comes same in both cases?
For a ternary operation as Mat says.
The answer to x>y>z really depends on the direction, the answer will vary from right to left , to left to right. but that is because of different comparisons done at different stage.
Both the answers will evaluate a value, but why do we say that we will chose only the one with left associativity
You are confused about operator precedence and operator associativity.
Operator associativity only applies with operators with the same precedence. For example:
1 - 2 + 3
+ and - have the same precedence, and they are left-associative, which means the above is equivalent to:
(1 - 2) + 3
The associativity concept come in play only when the expression has more than one operator. It is a property of the operator in the expression, not the operands. It define how brackets are inserted, not what the operator means.
operator : Some R
expression : x R y R z
left to right : (x R y) R z
right to left : x R (y R z)
edit:
Reference of operator associativity in C
You're confused between the Associativity and Readability.
Why use left associativity when the output comes same in both cases?
This is true for the readability but not for all the evaluations of expressions.
Consider:
x=10, y=20, z=10
Now, left to right associativity:
x<y<z => (x<y)<z => (10<20)<10 => (1<10) =>TRUE
Now, right to reft associativity:
x<y<z => x<(y<z) => 10<(20<10) => (10<0) =>FALSE
Now, the concept of associativity arrives only when there are multiple existence of same operator.
Example:
Operation 1:
d= c | y | z | a<<3 | b <<3 | x;
Operation 2:
m = c|y|z|x;
d = m | a<<3 | b<<3;
does operation 1 and operation 2 yield same results in C?
To answer the question in your title:
Are leftshift and OR operators commutative in C?
the | bitwise-or operator is commutative, but the << operator is not (a<<3 and 3<<a are quite different).
That doesn't appear to be what you meant to ask, though. To answer the body of your question, since << has higher precedence than | (i.e., << binds more tightly), you can think of a<<3 and b<<3 as if they were primary or parenthesized expressions. In effect, you have multiple subexpressions joined by | operators. Rearranging them should have no effect; your two code snippets should behave identically (except that the second one stores a value in m, which doesn't exist in your first snippet).
This assumes that all the variables you're using are of the same type. If they're not, then storing the intermediate value in m might involve a conversion which could alter the results. This probably doesn't apply in your case, but since you didn't show us any declarations it's impossible to be sure of that.
In this case, it should provide the same results since (a) there are no side effects (e.g. built-in pre- or post-increments or decrements), and (b) the << operator has higher precedence than |.
So, the << operations will occur before the | operations.
It's not a question of commutativity, but a question of precedence between operators. Although it does help that | itself is commutative since your choices do change the order in which expressions are or'ed together.
In perldata, I found the following examples and explanations.
#foo = ('cc', '-E', $bar);
assigns the entire list value to array #foo, but
$foo = ('cc', '-E', $bar);
assigns the value of variable $bar to the scalar variable $foo.
This really confuses me, so $foo is equivalent to $bar? How to understand the difference between #foo and $foo
The examples in perldata:
#foo = ('cc', '-E', $bar);
$foo = ('cc', '-E', $bar);
Because #foo creates a list context, all the values in the parens are assigned to #foo. $foo on the other hand is a scalar, and so is only assigned the last element in the list, because it is in scalar context.
It is equal to saying:
'cc', '-E';
$foo = $bar;
In Perl, a scalar, like $foo, can only hold a single value, and so the rest of the list is simply discarded. An array, like #foo will slurp as many values as the list holds.
In Perl, it is allowed to have the same name on variables of different types. #foo and $foo will be considered two different variables.
Expressions are allowed to have different meanings depending on which context they're evaluated in. The three main contexts are list, scalar, and void, though there exists several subcontexts of scalar context (boolean, string, and numeric being the most important ones).
The comma operator is no exception to this rule. In list context, the comma operator acts as a list concatenation operator, evaluating its operands in list context and combining the resulting lists into a single list. This is likely the context you're familiar with when dealing with the comma operator.
However, in scalar context, the comma operator functions much like the comma operator in C; it evaluates a sequence of expressions and discards their results, except for the rightmost expression which it returns (as a side note, the expressions that are discarded are evaluated in void context, and the expression that's returned is evaluated in scalar context). To learn how each of the perl operators behave in different contexts, I suggest reading perlop.
In order to fully understand context, you have to realize that the outermost operator enforces a context on its operands, whose operators then enforce a context on their operands, and so on (another side note: the outermost expression of a line is always evaluated in void context). So, for example, when the assignment operator is being used with an array or hash variable (beginning with a % or #), the right-hand side of the assignment is consequently evaluated in list context. If the variable is a scalar, however, the right-hand side of the assignment is evaluated in scalar context instead. This is why the comma operators in the assignments below:
#foo = ('cc', '-E', $bar);
$foo = ('cc', '-E', $bar);
act in completely different ways.
For more information on how you can write code that controls or reacts to context, read about the scalar and wantarray operators.