I have a code like
A = B|C|D|E;
Throwing the warning "suggest parentheses around arithmetic in operand of |"
Expecting that expression needs high priority paranthesis for operators, tried the following ways:
A=(B|C)|(D|E);
one more as :
A=(((B|C)|D)|E);
Still the same warning persists.
Please help me in resolving this.
Thanks,
Sujatha
B, C,D are enums and E is an integer.
You have some arithmetic operator in your expression that isn't really simply B, or that isn't really simply C, etc. The compiler is suggesting that you parenthesize whichever expression so that readers will see that you wrote what you meant. If you don't parenthesize, everyone has to remember exactly what the priorities are, and they have to figure out if you remembered when you wrote it.
Try this: (B)|(C)|(D)|(E).
This is a weird warning. You only really need to pay attention to precedence when you're using different operators and those operators have different precedences. For instance, in arithmetic multiplication has higher precedence than addition.
But in this case you're using only one operator multiple times. Bitwise or is associative and commutative ((A | B) | C == A | (B | C) and A | B == B | A) so there's really no reason for the warning.
Related
I have the following bitwise expression and was wondering if it could be simplified or if there is a general way of interpreting the output.
(x & y) | (~x & ~y)
The only "simpler" version is ~(x^y) (where ^ is the XOR operator).
However, It's not going to make a significant difference computationally, and is harder to read for most people (XOR is not as natural as AND and OR). There's not a simpler version using just AND and OR operators, so I would suggest you just leave it as-is.
if there is a general way of interpreting the output.
"Either both are true or both are false" is a natural interpretation.
I'm porting my game to Android which has around 200k lines of code and encountered a very strange bug, after 5 hours of digging I cracked it down to this line:
// background info
short m = ((dwMask << 4) | dwMask) << ASTAR_OFFSET_VIS;
short zm = (~ASTAR_MASK_DISCOVERED) | (~dwMask);
short *b = (short*)tilecache.GetDataPtr() + index;
// unexpected behavior
*b++ = (*b&zm) | m;
// works
*b = ((*b)&zm) | m; b++;
My guess is this compiler (GCC ARM) treats the ++ operator differently than all other compilers I've built this game on, which seems a little crazy, but not unbelievable. Previously the game has been built for Windows, Mac, iOS, and Windows CE and all processed the top version fine.
I think it's evaluating (*b&zm) | m then incrementing the pointer b++ then doing the assignment, because data is shifted left in my array each evaluation.
I have located numerous places in my code that use this type of syntax and changed them, but I want to make sure the problem is what I'm thinking it is, and if this is a compiler option I could switch to make it the same as the other compilers I use? In case I have other syntax like this in my code elsewhere.
The order in which arguments to functions or operators (including built-in operators) are evaluated is unspecified. Some compilers will evaluate the expressions from left to right, others evaluate them from right left. For some operators, e.g., the comma, the ternary, and the logic operators the order in which the arguments are evaluated and when side-effects happen is specified: the first operand is evaluated first.
This is unrelated to operator precedence which determines in which order the operators are evaluated. It is also unspecified when side-effects happen other than that they happen at the end of a full expression or after evaluating the first argument of one of the special operators.
What's happening first here in C++, shift or casting?
(dword)header[2]<<8
From here Operator precedence you can see that bitwise shift has lower precedence than type cast. So that is equivalent to:
((dword) (header[2])) << 8
Always use parentheses for things that are not clear, even if you check that it is actually ok, because it improves code readability. (you might not want to enclose the subscript like I did to emphasis all the precedences here, but use the other parenthesis).
I'm not looking for an implementation, just pseudo-code, or at least an algorithm to handle this effectively. I need to process statements like these:
(a) # if(a)
(a,b) # if(a || b)
(a+b) # if(a && b)
(a+b,c) # same as ((a+b),c) or if((a&&b) || c)
(a,b+c) # same as (a,(b|c)) or if(a || (b&&c))
So the + operator takes precedence over the , operator. (so my + is like mathematical multiplication with , being mathematical addition, but that is just confusing).
I think a recursive function would be best, so I can handle nested parentheses nice and easy by a recursive call. I'll also take care of error handling once the function returns, so no worries there. The problems I'm having:
I just don't know how to tackle the precedence thing. I could return true as soon as I see a , and the previous value was true. Otherwise, I'll rerun the same routine. A plus would effectively be a bool multiplication (ie true*true=true, true*false=false etc...).
Error detection: I've thought up several schemes to handle the input, but there are a lot of ugly bad things I want to detect and print an error to the user. None of the schemes I thought of handle errors in a unified (read: centralized) place in the code, which would be nice for maintainability and readability:
()
(,...
(+...
(a,,...
(a,+...
(a+,...
(a++...
Detecting these in my "routine" above should take care of bad input. Of course I'll check end-of-input each time I read a token.
Of course I'll have the problem of maybe having o read the full text file if there are unmatched parenthesis, but hey, people should avoid such tension.
EDIT: Ah, yes, I forgot the ! which should also be usable like the classic not operator:
(!a+b,c,!d)
Tiny update for those interested: I had an uninformed wild go at this, and wrote my own implementation from scratch. It may not be pretty enough for the die-hards, so hence this question on codereview.
The shunting-yard algorithm is easily implementable in a relatively short amount of code. It can be used to convert an infix expression like those in your examples into postfix expressions, and evaluation of a postfix expression is Easy-with-a-capital-E (you don't strictly need to complete the infix-to-postfix conversion; you can evaluate the postfix output of the shunting yard directly and just accumulate the result as you go along).
It handles operator precedence, parentheses, and both unary and binary operators (and with a little effort can be modified to handle infix ternary operators, like the conditional operator in many languages).
Write it in yacc (bison) it becomes trivial.
/* Yeacc Code */
%token IDENTIFIER
%token LITERAL
%%
Expression: OrExpression
OrExpression: AndExpression
| OrExpression ',' AndExpression
AndExpression: NotExpression
| AndExpression '+' NotExpression
NotExpression: PrimaryExpression
| '!' NotExpression
PrimaryExpression: Identifier
| Literal
| '(' Expression ')'
Literal: LITERAL
Identifier: IDENTIFIER
%%
There's probably a better (there's definitely a more concise) description of this, but I learned how to do this from this tutorial many years ago:
http://compilers.iecc.com/crenshaw/
It's a very easy read for non-programmers too (like me). You'll need only the first few chapters.
Studying the standard there was no information on how this will expand.
I tried it in visual studio 2008 and it does a = a * (b+c);
Does the standard guarantee that it will always expand to that and not a = a * b + c?
Was this always the way that expression expanded for all c++ standard versions?
Thanks.
Yes it's guaranteed.
a::operator*=(b + c);
EDIT:
Precedence isn't listed in a nice table in the standard, there's a footnote to 5/4 saying:
The precedence of operators is not
directly specified, but it can be
derived from the syntax.
The C++ Reference table is correct though.
Operators like =, *=, etc. have (almost) the lowest precedence (see this reference).
This means that whatever expressions you have on the right side of assignment operator, those expressions will be evaluated first. Then the result of evaluation will be assigned to the variable on the left side of assignment operator (multiplying along the way, in the case of *=).
a *= b + c does not "expand" to anything, *= is not a preprocessor macro.
Yes, modulo some obscure compiler bug the right side has always been evaluated as a unit.
*= is its own operator. It should amount to the same postconditions as writing a = a * (b + c) if the latter is valid but is not guaranteed to use the same path of execution to get there.
The + will have a higher precedence than the *= so it is guaranteed that b+c will be evaluated first, even if a is of a class type and *= is an overload.
*= is a separate operator. For all the built in functions it does the same thing as multiplication and assignment, and if you ever define it for one of your own classes you really SHOULD make it do the same thing, for obvious reasons. However, you wouldn't HAVE to.
That is, *= is its own operator, with its own precedence, and internally it will be represented as "multiplication, then assignment", but at no time is the line ever re-parsed with multiplication and assignment operators in.
Given that, there's two ways that line could possibly be parsed:
As a *= (b+c) (should have the same result as a = a * (b+c) for any sane types)
As (a*=b) + c (which assuming this is a stand-alone statement, will do multiply a by b, assign the result to a. It will then multiply the new value by c, but it will throw the result away)
So you can see, there's no precedence which would make it do "a = (a*b)+c" which is what you feared.
In fact, the second is clearly not very useful, and for this reason, all the assignment and something-assignment operators have lower precedence than arithmetic and other "normal" operations, in fact, lower precedence than anything except ",".
It's easy to check the precedence by googling and finding a table like:
http://www.cppreference.com/wiki/language/operator_precedence
I don't remember all of the details, so it's fine to check if you're not sure between similar operators, but you can do most of it by remembering the general principles like this one.