user1931177
user1931177

Reputation: 13

C++ bitwise OR operator

bool OrderUtils::shouldCptyAutoexecute(int Id)
{

bool res = 
    dummyCache::instance().getVal(Id).getWhitelabelType() == "ABCD";
if (!res)
    res |= dummyCache::instance().getVal(Id).getIsPlc() == 1;

return res;
}

The above code checks for 2 Id's and returns true to res if any of the id is present in the database.

Can you suggest a way in which I can compare one more value from the databse table and return true to the value res..Also can you explain what does the second if statement do and the bitwise OR operator?

Upvotes: 1

Views: 213

Answers (1)

WhozCraig
WhozCraig

Reputation: 66254

Sir, just let the short-circuit eval do this for you:

return dummyCache::instance().getVal(Id).getWhitelabelType() == "ABCD" ||
       dummyCache::instance().getVal(Id).getIsPlc() == 1;

If the first is true, the second will not fire. Moreover, I assure you a remotely-reasonable optimizing compiler will not re-fire instance().getVal(id) if the returned object has not changed between the getWhitelabelType() and getisPlc() calls. In fact, i would all-but-guarantee it if getWhiteLabelType() is const. (and it certainly looks like it should be).

Regarding the bit work. The expression was pretty-much whacked. though it will work. Unless I read it wrong (and trust me, the list of people that will tell me I am will let me know quickly) it is performing a boolean eval, promoting the resulting true/false bool to an int, promoting the current value of res from bool to int (which is zero, so nothing special there), bitwise-OR-ing that with the expression int, then demoting the final int back to a bool to store in res . I'm surprised this doesn't flag at least a warning on the compiler.

It likely should have been if (!res) res ||= expr, and even then, it is pointless, as you can just use short circuit eval as in the top of this answer to cut out the local res entirely. Consider if res were false. Then the equivalent expression would be res = false || expr. But thats just res = expr. In the !res state it executes in, you may as well just use an assignment.

Finally, regarding adding a third field to your eval, it depends entirely on how you want it added. for an additional logical OR it is pretty simple.

For an expression like (A || B || C) you can just

return dummyCache::instance().getVal(Id).AField() == ATestValue ||
       dummyCache::instance().getVal(Id).BField() == BTestValue ||
       dummyCache::instance().getVal(Id).CField() == CTestValue;

For more complex operations, some judicious use of parenthesis will go a long way. For example, to return (A || B) && C:

return (dummyCache::instance().getVal(Id).AField() == ATestValue ||
        dummyCache::instance().getVal(Id).BField() == BTestValue) &&
       dummyCache::instance().getVal(Id).CField() == CTestValue;

Or perhaps (A && C) || (B && !C) (ok this is getting a little overboard...)

return (dummyCache::instance().getVal(Id).CField() == CTestValue) 
       ? (dummyCache::instance().getVal(Id).AField() == ATestValue)
       : (dummyCache::instance().getVal(Id).BField() == BTestValue);

Upvotes: 3

Related Questions