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.
Best Answer
Regardless of compiler, you can always save on runtime if you can afford to do
instead of
The former involves only one comparison of
std::type_info
; the latter necessarily involves traversing an inheritance tree plus comparisons.Past that ... like everyone says, the resource usage is implementation specific.
I agree with everyone else's comments that the submitter should avoid RTTI for design reasons. However, there are good reasons to use RTTI (mainly because of boost::any). That in mind, it's useful to know its actual resource usage in common implementations.
I recently did a bunch of research into RTTI in GCC.
tl;dr: RTTI in GCC uses negligible space and
typeid(a) == typeid(b)
is very fast, on many platforms (Linux, BSD and maybe embedded platforms, but not mingw32). If you know you'll always be on a blessed platform, RTTI is very close to free.Gritty details:
GCC prefers to use a particular "vendor-neutral" C++ ABI[1], and always uses this ABI for Linux and BSD targets[2]. For platforms that support this ABI and also weak linkage,
typeid()
returns a consistent and unique object for each type, even across dynamic linking boundaries. You can test&typeid(a) == &typeid(b)
, or just rely on the fact that the portable testtypeid(a) == typeid(b)
does actually just compare a pointer internally.In GCC's preferred ABI, a class vtable always holds a pointer to a per-type RTTI structure, though it might not be used. So a
typeid()
call itself should only cost as much as any other vtable lookup (the same as calling a virtual member function), and RTTI support shouldn't use any extra space for each object.From what I can make out, the RTTI structures used by GCC (these are all the subclasses of
std::type_info
) only hold a few bytes for each type, aside from the name. It isn't clear to me whether the names are present in the output code even with-fno-rtti
. Either way, the change in size of the compiled binary should reflect the change in runtime memory usage.A quick experiment (using GCC 4.4.3 on Ubuntu 10.04 64-bit) shows that
-fno-rtti
actually increases the binary size of a simple test program by a few hundred bytes. This happens consistently across combinations of-g
and-O3
. I'm not sure why the size would increase; one possibility is that GCC's STL code behaves differently without RTTI (since exceptions won't work).[1] Known as the Itanium C++ ABI, documented at http://www.codesourcery.com/public/cxx-abi/abi.html. The names are horribly confusing: the name refers to the original development architecture, though the ABI specification works on lots of architectures including i686/x86_64. Comments in GCC's internal source and STL code refer to Itanium as the "new" ABI in contrast to the "old" one they used before. Worse, the "new"/Itanium ABI refers to all versions available through
-fabi-version
; the "old" ABI predated this versioning. GCC adopted the Itanium/versioned/"new" ABI in version 3.0; the "old" ABI was used in 2.95 and earlier, if I am reading their changelogs correctly.[2] I couldn't find any resource listing
std::type_info
object stability by platform. For compilers I had access to, I used the following:echo "#include <typeinfo>" | gcc -E -dM -x c++ -c - | grep GXX_MERGED_TYPEINFO_NAMES
. This macro controls the behavior ofoperator==
forstd::type_info
in GCC's STL, as of GCC 3.0. I did find that mingw32-gcc obeys the Windows C++ ABI, wherestd::type_info
objects aren't unique for a type across DLLs;typeid(a) == typeid(b)
callsstrcmp
under the covers. I speculate that on single-program embedded targets like AVR, where there is no code to link against,std::type_info
objects are always stable.