如何使用MSVC内在函数来获得相当于这个GCC代码?

以下代码在GCC中调用clz / ctz的内置函数,在其他系统上调用C版本。 显然,如果系统有内置的clz / ctz指令,如x86和ARM,则C版本有点不理想。

#ifdef __GNUC__ #define clz(x) __builtin_clz(x) #define ctz(x) __builtin_ctz(x) #else static uint32_t ALWAYS_INLINE popcnt( uint32_t x ) { x -= ((x >> 1) & 0x55555555); x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); x = (((x >> 4) + x) & 0x0f0f0f0f); x += (x >> 8); x += (x >> 16); return x & 0x0000003f; } static uint32_t ALWAYS_INLINE clz( uint32_t x ) { x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return 32 - popcnt(x); } static uint32_t ALWAYS_INLINE ctz( uint32_t x ) { return popcnt((x & -x) - 1); } #endif 

我需要调用哪些函数,我需要包含哪些标题等,以便在此处为MSVC添加正确的ifdef? 我已经看过这个页面 ,但是我不完全确定#pragma是什么(它是否需要?)以及它对编译的MSVC版本要求有什么限制。 作为一个并不真正使用MSVC的人,我也不知道这些内在函数是否在其他体系结构上具有C等价物,或者在#defining它们时是否还需要#ifdef x86 / x86_64。

从sh0dan代码反弹,实现应该像这样纠正:

 #ifdef _MSC_VER #include  uint32_t __inline ctz( uint32_t value ) { DWORD trailing_zero = 0; if ( _BitScanForward( &trailing_zero, value ) ) { return trailing_zero; } else { // This is undefined, I better choose 32 than 0 return 32; } } uint32_t __inline clz( uint32_t value ) { DWORD leading_zero = 0; if ( _BitScanReverse( &leading_zero, value ) ) { return 31 - leading_zero; } else { // Same remarks as above return 32; } } #endif 

如代码中所述,如果value为0,则ctz和clz都是未定义的。在我们的抽象中,我们将__builtin_clz(value)(value?__builtin_clz(value):32)但它是一个选择

如果MSVC有一个内在的编译器,它将在这里:

MSDN上的编译器内在函数

否则,你必须使用__asm编写它

在linux和windows(x86)上测试:

 #ifdef WIN32 #include  static uint32_t __inline __builtin_clz(uint32_t x) { unsigned long r = 0; _BitScanReverse(&r, x); return (31-r); } #endif uint32_t clz64(const uint64_t x) { uint32_t u32 = (x >> 32); uint32_t result = u32 ? __builtin_clz(u32) : 32; if (result == 32) { u32 = x & 0xFFFFFFFFUL; result += (u32 ? __builtin_clz(u32) : 32); } return result; } 

有两个内在函数“_BitScanForward”和“_BitScanReverse”,它们适用于MSVC。 包括。 function是:

 #ifdef _MSC_VER #include  static uint32_t __inline ctz( uint32_t x ) { int r = 0; _BitScanReverse(&r, x); return r; } static uint32_t __inline clz( uint32_t x ) { int r = 0; _BitScanForward(&r, x); return r; } #endif 

有等效的64位版本“_BitScanForward64”和“_BitScanReverse64”。

在这里阅读更多:

x86 MSDN上的内在函数