Below are the results of compiling 5 "different" versions of a
non-templatized free function "CheckBit" without any compiler
optimizations turned on. Version E shows the desired implementation but
it cannot be had because CheckBit is, in reality, a template function
(the functions below are only to analyze and evaluate effects of various
implementations of CheckBit) and the "impedance mismatch" between
templates and the C++ type system will not allow version E to be
generated by the template machinery (consider that desired is to generate
CheckBit for all unsigned integer types, include a platform-specific
64-bit unsigned integer). Note that A, C and E generate the same assembly
and that B and D result in more instructions than A, C, E (but please
note that they look longer than they are because of the embedded line
number comments).. Full optimization had no effect on the code generated.
(It should be clear that "uint32" is an alias and the the suffixes used
in version E are non-standard).
11 //A.
12 //
13 #define CBTYPE uint32
14 #define INLINE
15 INLINE bool CheckBitA(CBTYPE mask, uint32 n)
16 {
17 return ((mask & ((CBTYPE)1) << (n-((CBTYPE)1))) != 0);
18 }
19
20 //B.
21 //
22 INLINE bool CheckBitB(CBTYPE mask, uint32 n)
23 {
24 const CBTYPE one(1);
25 return ((mask & (one << (n-one))) != 0);
26 }
27
28 //C.
29 //
30 INLINE bool CheckBitC(CBTYPE mask, uint32 n)
31 {
32 return ((mask & (CBTYPE(1) << (n-1))) != 0);
33 }
34
35 //D.
36 //
37 INLINE bool CheckBitD(CBTYPE mask, uint32 n)
38 {
39 CBTYPE bit = CBTYPE(1) << (n-1);
40 return ((mask & bit) != 0);
41 }
42
43 //E.
44 //
45 INLINE bool CheckBitE(CBTYPE mask, uint32 n)
46 {
47 return ((mask & (1ui32 << (n-1ui32))) != 0);
48 }
Generated Assembly (Release Build, Unoptimized, CBTYPE: uint32, INLINE: )
Compiler: VC++ 2010, Intrinsics: Off, Whole Program Optimization: Off.
// A
; Line 16
push ebp
mov ebp, esp
; Line 17
mov ecx, DWORD PTR _n$[ebp]
sub ecx, 1
mov eax, 1
shl eax, cl
and eax, DWORD PTR _mask$[ebp]
neg eax
sbb eax, eax
neg eax
; Line 18
pop ebp
ret 8
// B
; Line 23
push ebp
mov ebp, esp
push ecx
; Line 24
mov DWORD PTR _one$[ebp], 1
; Line 25
mov ecx, DWORD PTR _n$[ebp]
sub ecx, 1
mov eax, 1
shl eax, cl
and eax, DWORD PTR _mask$[ebp]
neg eax
sbb eax, eax
neg eax
; Line 26
mov esp, ebp
pop ebp
ret 8
// C
; Line 31
push ebp
mov ebp, esp
; Line 32
mov ecx, DWORD PTR _n$[ebp]
sub ecx, 1
mov eax, 1
shl eax, cl
and eax, DWORD PTR _mask$[ebp]
neg eax
sbb eax, eax
neg eax
; Line 33
pop ebp
ret 8
// D
; Line 38
push ebp
mov ebp, esp
push ecx
; Line 39
mov ecx, DWORD PTR _n$[ebp]
sub ecx, 1
mov eax, 1
shl eax, cl
mov DWORD PTR _bit$[ebp], eax
; Line 40
mov eax, DWORD PTR _mask$[ebp]
and eax, DWORD PTR _bit$[ebp]
neg eax
sbb eax, eax
neg eax
; Line 41
mov esp, ebp
pop ebp
ret 8
//E.
; Line 46
push ebp
mov ebp, esp
; Line 47
mov ecx, DWORD PTR _n$[ebp]
sub ecx, 1
mov eax, 1
shl eax, cl
and eax, DWORD PTR _mask$[ebp]
neg eax
sbb eax, eax
neg eax
; Line 48
pop ebp
ret 8