Why compare a flag with the result of bitwise AND of a bitmask and the flag? - bit-manipulation

As a follow-up to "How to use bitmask": When I want to test if a certain flag is set in a given bitmask, I would usually do so solely through the usage of a bitwise AND:
if(bitmask & flag) { …
Yet I frequently see something like this:
if((bitmask & flag) == flag) { …
This is something I observed on both, strongly and weakly typed languages, which is ruling out some sort of prevention for type-casting disasters. The only scenario I can come up with in which the two tests were not equivalent were if flag happens to have actually more than one bit set and all of those are required to be set in bitmask for the condition to pass. Is that all or am I missing something here?
Bonus: Do compilers have means to recognize a flag that will have at most one bit set during runtime and optimize the (possibly bogus) comparison away?

As you point out, the two conditions aren't equivalent. The check (bitmask & flag)1 is checking if any bit set in flag is set in bitmask, while the (bitmask & flag) == flag check checks if all bits in flag are set.
In cases where there will only ever be one bit set, you might also see the second form rather than the first in languages like Java that don't have an implicit conversion from integral types to boolean. The exact equivalent of the first check in those languages is (bitmask & flag) != 0 and that form is probably also more canonical even for checking a single flag.
In terms of actual generated code it's mostly all academic.
For known-at-compile-time2 flags where the compiler can see that the flag only has one bit, both forms will generally be compiled to identical code - see the fixedA and fixedB functions in that link.
For functions with unknown flags, the forms aren't equivalent, as mentioned, so the code is different (see the unknownA and B functions) but the performance difference is very minor.
1 Or, equivalently, (bitmask & flag) != 0 in languages that don't have an implicit conversion from integer types to boolean.
2 Importantly, this includes functions that accept variable flags but where the caller is using a constant flag and the function is inlined.

Related

C++ conversion from int to bool

I want to know if the compiled code of a bool-to-int conversion contains a branch (jump) operation.
For example, given void func(bool b) and int i:
Is the compiled code of calling func(i) equivalent to the compiled code of func(i? 1:0)?
Or is there a more elaborate way for the compiler to perform this without the branch operation?
Update:
In other words, what code does the compiler generate in order to push 1 or 0 into the stack before jumping to the address of the function?
I assume that it really comes down to the architecture of the CPU at hand, and that some specific processors (certain DSPs, for example) may support this. So my question refers to "conventional" general-purpose CPUs (assuming that this definition is acceptable).
In terms of pure software, the question can also be phrased as: is there an efficient way for converting an integer value to 1 when it's not 0, and to 0 otherwise, without using a conditional statement?
Thanks
It's not your (compiler user) job too make built-in type conversion efficient. If the compiler is not dumb, it will make that sort of things as close as the CPU representation are.
For the most of the commercial CPU, bool and int are the exact same thing, and if(x) { ... }
translate in bit-anding (or bit-oring, whichever is faster: they are normally immediate instructions) x with itself and make a conditional jump after the } if the zero flag is set. (not that this is just a trick to force the zero-flag computation, that is an immediate consequence of the arithmetic unit electronics)
variants are much more a matter of CPU electronics, than code. So don'care about it. ifs are not triggered by a bool, but by the last arithmetic operation result.
Whatever arithmetic operation held by a CPU produces a result ans set some flags that represent certain result attributes: if it is zero, if it produced a carry or borrow, if it has an odd or even number of bit set to 1 etc. Resut and Flags are two registers, and can be loaded and stored from/to memory.

Check if certain bits are set in a DWORD

My question: I'm looking at the Characteristics member of the IMAGE_SECTION_HEADER struct. I want to know if a certain section is executable or not. How would I go about checking this? The Characteristics member is a DWORD, and I want to be able to know if it contains the value IMAGE_SCN_MEM_EXECUTE (0x20000000). What would the calculation for this look like? I'm guessing I have to use the modulo operator, but have no idea how.
if (imageSectionHeader.Characteristics & IMAGE_SCN_MEM_EXECUTE)
{
// Do work here...
}
This is called masking. You're masking the Characteristics value with IMAGE_SCN_MEM_EXECUTE mask to see if those specific bits are set. The condition above will only be true if all the bits set in the IMAGE_SCN_MEM_EXECUTE mask are also set in the Characteristics value.
It looks like IMAGE_SECTION_HEADER::Characteristics is a bit field. You want to check if the bit denoted by IMAGE_SCN_MEM_EXECUTE is set. To do that, you do the bitwise AND between Characteristics and IMAGE_SCN_MEM_EXECUTE:
header.Characteristics & IMAGE_SCN_MEM_EXECUTE
When converted to bool, this expression will be true only if the IMAGE_SCN_MEM_EXECUTE bit is set.
Found some facts about windows flag design :
Lets assume Flag A is "0x0001000", B is "0x0002000" and C is "0x0003000".
Characteristics may contain multibyte flag. Suppose exe contains flag A & B.
Then Characteristics value will be "0x0003000".
if we are checking (Characteristics&(A|B)) this will be okay but (Characteristics&(C)) will also return true.
But Microsoft designed flags in such way that no multiple flags having possibility to come together and form third flag.
If we check possible values of Characteristics closly, there are some intermediate values which are skipped to avoid above issue.
Bitwise AND(&) will always work for flag checking.
For Safety one can also write expression as follows:
if we wants to check for Flag1 & Flag2 in Characteristics.
((Characteristics & (Flag1|Flag2|Highest Bit flag in flag list)==(Flag1|Flag2))

Can I guarantee the C++ compiler will not reorder my calculations?

I'm currently reading through the excellent Library for Double-Double and Quad-Double Arithmetic paper, and in the first few lines I notice they perform a sum in the following way:
std::pair<double, double> TwoSum(double a, double b)
{
double s = a + b;
double v = s - a;
double e = (a - (s - v)) + (b - v);
return std::make_pair(s, e);
}
The calculation of the error, e, relies on the fact that the calculation follows that order of operations exactly because of the non-associative properties of IEEE-754 floating point math.
If I compile this within a modern optimizing C++ compiler (e.g. MSVC or gcc), can I be ensured that the compiler won't optimize out the way this calculation is done?
Secondly, is this guaranteed anywhere within the C++ standard?
You might like to look at the g++ manual page: http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Optimize-Options.html#Optimize-Options
Particularly -fassociative-math, -ffast-math and -ffloat-store
According to the g++ manual it will not reorder your expression unless you specifically request it.
Yes, that is safe (at least in this case). You only use two "operators" there, the primary expression (something) and the binary something +/- something (additive).
Section 1.9 Program execution (of C++0x N3092) states:
Operators can be regrouped according to the usual mathematical rules only where the operators really are associative or commutative.
In terms of the grouping, 5.1 Primary expressions states:
A parenthesized expression is a primary expression whose type and value are identical to those of the enclosed expression. ... The parenthesized expression can be used in exactly the same contexts as those where the enclosed expression can be used, and with the same meaning, except as otherwise indicated.
I believe the use of the word "identical" in that quote requires a conforming implementation to guarantee that it will be executed in the specified order unless another order can give the exact same results.
And for adding and subtracting, section 5.7 Additive operators has:
The additive operators + and - group left-to-right.
So the standard dictates the results. If the compiler can ascertain that the same results can be obtained with different ordering of the operations then it may re-arrange them. But whether this happens or not, you will not be able to discern a difference.
This is a very valid concern, because Intel's C++ compiler, which is very widely used, defaults to performing optimizations that can change the result.
See http://software.intel.com/sites/products/documentation/hpc/compilerpro/en-us/cpp/lin/compiler_c/copts/common_options/option_fp_model.htm#option_fp_model
I would be quite surprised if any compiler wrongly assumed associativity of arithmetic operators with default optimising options.
But be wary of extended precision of FP registers.
Consult compiler documentation on how to ensure that FP values do not have extended precision.
If you really need to, I think you can make a noinline function no_reorder(float x) { return x; }, and then use it instead of parenthesis. Obviously, it's not a particularly efficient solution though.
In general, you should be able to -- the optimizer should be aware of the properties of the real operations.
That said, I'd test the hell out of the compiler I was using.
Yes. The compiler will not change the order of your calculations within a block like that.
Between compiler optimizations and out-of-order execution on the processor, it is almost a guarantee that things will not happen exactly as you ordered them.
HOWEVER, it is also guaranteed that this will NEVER change the result. C++ follows standard order of operations and all optimizations preserve this behavior.
Bottom line: Don't worry about it. Write your C++ code to be mathematically correct and trust the compiler. If anything goes wrong, the problem was almost certainly not the compiler.
As per the other answers you should be able to rely on the compiler doing the right thing -- most compilers allow you to compile and inspect the assembler (use -S for gcc) -- you may want to do that to make sure you get the order of operation you expect.
Different optimization levels (in gcc, -O _O2 etc) allows code to be re-arranged (however sequential code like this is unlikely to be affected) -- but I would suggest you should then isolate that particular part of code into a separate file, so that you can control the optimization level for just the calculation.
The short answer is: the compiler will probably change the order of your calculations, but it will never change the behavior of your program (unless your code makes use of expression with undefined behavior: http://blog.regehr.org/archives/213)
However, you can still influence this behavior by deactivating all compiler optimizations (option "-O0" with gcc). If you still needs the compiler to optimize the rest of your code, you may put this function in a separate ".c" which you can compile with "-O0".
Additionally, you can use some hacks. For instance, if you interleaves your code with extern function calls the compiler may consider that it is unsafe to re-order your code as the function may have unknown side-effect. Calling "printf" to print the value of your intermediate results will conduct to similar behavior.
Anyway, unless you have any very good reason (e.g. debugging) you typically don't want to care about that, and you should trust the compiler.

Efficency of repeated arithmetic between two macros

In an ANSI C project I am working on, I have two macros defined: PERIOD_IN_MS and CYCLES_PER_MS. In the actual period handling logic, I do many comparisons between a counter that is incremented every ''cycle'' and PERIOD_IN_MS * CYCLES_PER_MS. I'm concerned that this arithmetic operation is repeatedly evaluated during each comparison.
Does anyone know if this is true, or if the compiler will evaluate the product of the two integer literals at compile time and use that instead?
I realize that this particular example would probably only remove one instruction out of the generated assembly code, but now I'm curious about this.
The standard doesn't impose any requirement to do this, but any sensible compiler will fold these constants down into one at compile-time. See e.g. http://en.wikipedia.org/wiki/Constant_propagation.
If you're curious to know whether this has actually happened, you can always take a look at the assembler generated by the compiler.
The compiler should (but I believe in C is not required to) evaluate the constant expression at compile-time. A good compiler will almost certainly do it, though, when optimization is turned on.
If you want to avoid multiple evaluation, maybe just to speed up compilation and your constants fit into int, you could enforce single evaluation by using an enumeration constant, instead.
enum { cycles_per_period = PERIOD_IN_MS * CYCLES_PER_MS};

Prevent misuse of logical operator instead of bitwise operators

In C++ it's possible to use a logical operator where a biwise operator was intended:
int unmasked = getUnmasked(); //some wide value
int masked = unmasked & 0xFF; // izolate lowest 8 bits
the second statement could be easily mistyped:
int masked = unmasked && 0xFF; //&& used instead of &
This will cause incorrect behaviour - masked will now be either 0 or 1 when it is inteded to be from 0 to 255. And C++ will not ever complain.
Is is possible to design code in such a way that such errors are detected at compiler level?
Ban in your coding standards the direct use of any bitwise operations in an arbitrary part of the code. Make it mandatory to call a function instead.
So instead of:
int masked = unmasked & 0xFF; // izolate lowest 8 bits
You write:
int masked = GetLowestByte(unmasked);
As a bonus, you'll get a code base which doesn't have dozens of error prone bitwise operations spread all over it.
Only in one place (the implementation of GetLowestByte and its sisters) you'll have the actual bitwise operations. Then you can read these lines two or three times to see if you blew it. Even better, you can unit test that part.
This is a bit Captain Obvious, but you could of course apply encapsulation and just hide the bitmask inside a class. Then you can use operator overloading to make sure that the boolean operator&&() as you see fit.
I guess that a decent implementation of such a "safe mask" need not be overly expensive performance-wise, either.
In some instances you might get a compiler warning (I wouldn't expect one in your example though). A tool like lint might be able to spot possible mistakes.
I think the only way to be sure is to define your coding standards to make the difference between the two operators more obvious - something like:
template<typename T>
T BitwiseAnd( T value, T mask ) { return value & mask; }
and ban the bitwise operators & and |
Both operators represent valid operations on integers, so I don't see any way of detecting a problem. How is the compiler supposed to know which operation you really wanted?