In this MSDN article on file sharing mode with std::ofstream, Microsoft writes:
To combine the filebuf::sh_read and filebuf::sh_write modes, use the logical OR (||) operator.
Both constants are of type int, as far as I can see, so I don't understand why we should use the logical OR instead of the bitwise OR (|). I always thought that the logical OR produces a Boolean value, so there is no way of interpreting the result?
It is a documentation error. In later versions, they have restructured the documentation, delegating the explanation of bitmask types to the following page:
A bitmask type can be implemented as either an integer type or an enumeration. In either case, you can perform bitwise operations (such as AND and OR) on values of the same bitmask type. The elements A and B of a bitmask type are nonzero values such that A & B is zero.
Get there via
google
http://msdn.microsoft.com/en-us/library/5785s5ts(v=vs.71).aspx
http://msdn.microsoft.com/en-us/library/7z434859(v=vs.71).aspx
http://msdn.microsoft.com/en-us/library/t60aakye(v=VS.71).aspx
http://msdn.microsoft.com/en-us/library/y1et11xw(v=VS.71).aspx
http://msdn.microsoft.com/en-us/library/5kb732k7(v=VS.71).aspx
Yay! for MSDN navigation. Also, VS2010 documentation has been altered again: the newest page doesn't even describe the semantics of the flags fields anymore (allthough, you could take one mention of _Mode | ios_base::out to imply that the params are bitmask combinations)
Related
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.
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))
screen = SDL_SetVideoMode(1000,1000,32, SDL_HWSURFACE | SDL_FULLSCREEN);
What does the | do in SDL_HWSURFACE | SDL_FULLSCREEN? (I tried googling this but google wont accept special characters..)
C / C++ APIs often set up bit 'flags' when there are a lot of different, non-mutually exclusive options that can be set for a given function call. Each of the flags will be assigned a bit position in a value (often a DWORD or other large integer type). One or more of these bits can then be set by bitwise OR-ing a collection of defined constants that represent the options and give you a more clear label to identify them than a raw numeric constant. The resultant value is passed as a single argument to the API function, which helps to keep the signature manageable.
In this particular case, SDL_HWSURFACE and SDL_FULLSCREEN represent options that can be passed in to the SDL_SetVideoMode call. There are probably several other possible options available as well that were not set in this case. This particular call sets the two options by bitwise OR-ing the flag constants together, and passing the result as the last parameter.
That's the bitwise OR operator. It applies it to SDL_HWSURFACE and SDL_FULLSCREEN.
The other answers have explained it's a bitwise OR, but you probably want to know how that works:
The flags are passed as a binary number, like 00001000 or 01000000, and each bit represents an individual flag. So the first bit (0) means HW_SURFACE is off, and the second bit (1) means FULLSCREEN is on. (Note that these are examples, I'm not sure about the actual bits.)
So what the bitwise OR function does is combine those two flags by comparing each bit and saying "Is this bit OR this bit 1?" and if either is 1, it will set the result to 1. This will provide the result 01001000 which can be parsed by SDL to set the appropriate flags.
The | operator means bitwise or. That means each bit in the result is set if the corresponding bit in the left hand or the right hand value is set. So 1 | 2 = 3, because 1 in binary is 01 and 2 in binary is 10. So the result in binary is 11 which is 3 in decimal.
In your example this is used to pass a lot of different on/off options to a function. Each of the constants has exactly one bit set. The function then looks at the value you pass and using the bitwise and operator & to check which ones you specified.
I'm working with a function that uses bitwise operations with the length of a file: fpos_t flen;
When I try casting it to an int or char, or attempt on arithmetic operation on it, it fails with the following compilation error:
error: aggregate value used where an integer was expected
You're misusing that type. First, it doesn't represent a length. It represents a position. Second, it's only meant to use in a call to fsetpos. You're not meant to do arithmetic on it because it doesn't necessarily represent a numeric type. It contains whatever information your library needs to be able to perform an fsetpos operation. In your library's implementation, fpos_t appears to be an aggregate type, such as a struct. (You can check the definition in the header files to be sure, but don't rely on whatever you discover there; it's liable to differ on other platforms or in future versions of your standard library.)
As for your next step, consider asking a more direct question about how to solve whatever problem you were working on when you came up with the idea to do bitwise operations on a fpos_t.
I was getting the same error when i was trying to do this:
char aux = (char)flen & 15, where flen was fpos_t.
I found a solution here: http://dsmarkchen.blogspot.com.br/2008/08/fpost.html .
It should be:
char aux = flen.__pos & 15.
It sounds like you want to work with current file position as an integer. If so, you'll probably want to use ftell/fseek (or their 64-bit brethren), rather than fgetpos/fsetpos. Both serve analogous operations, but ftell/fseek work with integral values, while fgetpos/fsetpos work with an intentionally-abstract structure.
I just saw a code snippet with a piece of syntax that I have never seen before.
What does bool start : 1; mean? I found it inside a class definition in a header file.
struct record {
char *name;
int refcount : 4;
unsigned dirty : 1;
};
Those are bit-fields; the number gives the exact size of the field, in bits. (See any complete book on C for the details.) Bit-fields can be used to save space in structures having several binary flags or other small fields, and they can also be used in an attempt to conform to externally-imposed storage layouts. (Their success at the latter task is mitigated by the fact that bit-fields are assigned left-to-right on some machines and right-to-left on others).
Note that the colon notation for specifying the size of a field in bits is only valid in structures (and in unions); you cannot use this mechanism to specify the size of arbitrary variables.
References: K&R1 Sec. 6.7 pp. 136-8
K&R2 Sec. 6.9 pp. 149-50
ISO Sec. 6.5.2.1
H&S Sec. 5.6.5 pp. 136-8
it's a bitfield. : 1 means one bit is used.
see for example http://msdn.microsoft.com/en-us/library/ewwyfdbe(VS.71).aspx
It means that start is 1 bit wide, as opposed to the normal bool which is 1 byte long. You can pack multiple smaller variables into a larger variable and the compiler will generate all the and/or code necessary to read/write it for you. You will take a (noticeable) performance hit, but, if used right, you'll use a lot less memory.
See the Wikipedia entry about Bit Fields. It tells the compiler how many bits the structure member should occupy.
It makes the member start into a bit-field, with 1 bit of space reserved.
It's only valid for struct/class members, you can't have a bit-field variable.
This is the syntax for bit fields
Essentially, you define a field in a struct to have only a few bits of a full byte or short or int.
Several bit fields may share the same int so this method can be used as a clever way to avoid some bit manipulations in constructing values.
This is the syntax for describing bit fields. This is a way of packing more information into a smaller amount of storage. Whereas normally a bool would take at least a byte (probably more) to represent, by using bit fields, you can combine several bools into one byte with a simple syntax.
Be careful though. As one of lesser-known areas of the language, you may run into corner cases when using them. For example, the data structures thus produced are probably not portable between processor types.
It's a bit-field. But I've never tried making bit-fields on boolean.