Setting a bit
Use the bitwise OR operator (|
) to set a bit.
number |= 1UL << n;
That will set the n
th bit of number
. n
should be zero, if you want to set the 1
st bit and so on upto n-1
, if you want to set the n
th bit.
Use 1ULL
if number
is wider than unsigned long
; promotion of 1UL << n
doesn't happen until after evaluating 1UL << n
where it's undefined behaviour to shift by more than the width of a long
. The same applies to all the rest of the examples.
Clearing a bit
Use the bitwise AND operator (&
) to clear a bit.
number &= ~(1UL << n);
That will clear the n
th bit of number
. You must invert the bit string with the bitwise NOT operator (~
), then AND it.
Toggling a bit
The XOR operator (^
) can be used to toggle a bit.
number ^= 1UL << n;
That will toggle the n
th bit of number
.
Checking a bit
You didn't ask for this, but I might as well add it.
To check a bit, shift the number n to the right, then bitwise AND it:
bit = (number >> n) & 1U;
That will put the value of the n
th bit of number
into the variable bit
.
Changing the nth bit to x
Setting the n
th bit to either 1
or 0
can be achieved with the following on a 2's complement C++ implementation:
number ^= (-x ^ number) & (1UL << n);
Bit n
will be set if x
is 1
, and cleared if x
is 0
. If x
has some other value, you get garbage. x = !!x
will booleanize it to 0 or 1.
To make this independent of 2's complement negation behaviour (where -1
has all bits set, unlike on a 1's complement or sign/magnitude C++ implementation), use unsigned negation.
number ^= (-(unsigned long)x ^ number) & (1UL << n);
or
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
It's generally a good idea to use unsigned types for portable bit manipulation.
or
number = (number & ~(1UL << n)) | (x << n);
(number & ~(1UL << n))
will clear the n
th bit and (x << n)
will set the n
th bit to x
.
It's also generally a good idea to not to copy/paste code in general and so many people use preprocessor macros (like the community wiki answer further down) or some sort of encapsulation.
I have battled this problem myself last week and consider myself somewhat of an expert now ;)
I'm 99% sure that not all dlls and static libraries were recompiled with the SP1 version. You need to put
#define _BIND_TO_CURRENT_MFC_VERSION 1
#define _BIND_TO_CURRENT_CRT_VERSION 1
into every project you're using. For every project of a real-world size, it's very easy to forget some small lib that wasn't recompiled.
There are more flags that define what versions to bind to; it's documented on http://msdn.microsoft.com/en-us/library/cc664727%28v=vs.90%29.aspx . As an alternative to the lines above, you can also put
#define _BIND_TO_CURRENT_VCLIBS_VERSION 1
which will bind to the latest version of all VC libs (CRT, MFC, ATL, OpenMP).
Then, check what the embedded manifest says. Download XM Resource Editor: http://www.wilsonc.demon.co.uk/d10resourceeditor.htm. Open every dll and exe in your solution. Look under 'XP Theme Manifest'. Check that the 'version' attribute on the right-hand side is '9.0.30729.1'. If it's '9.0.21022', some static library is pulling in the manifest for the old version.
What I found is that in many cases, both versions were included in the manifest. This means that some libraries use the sp1 version and others don't.
A great way to debug which libraries don't have the preprocessor directives set: temporarily modify your platform headers so that compilation stops when it tries to embed the old manifest. Open C:\Program Files\Microsoft Visual Studio 9.0\VC\crt\include\crtassem.h. Search for the '21022' string. In that define, put something invalid (change 'define' to 'blehbleh' or so). This way, when you're compiling a project where the _BIND_TO_CURRENT_CRT_VERSION
preprocessor flag is not set, your compilation will stop and you'll know that you need to add them or made sure that it's applied everywhere.
Also make sure to use Dependency Walker so that you know what dlls are being pulled in. It's easiest to install a fresh Windows XP copy with no updates (only SP2) on a virtual machine. This way you know for sure that there is nothing in the SxS folder that is being used instead of the side-by-side dlls that you supplied.
Best Answer
I never found anything definite on this, although you could look in the
winsxs
folder in the userswindir
for the right folders and files.I've got our app's installer running it quietly when they install, which won't cause any problems if it is already there.