移位计数 >= 类型和宏的宽度与内联函数
shift count >= width of type and macros vs inline function
我正在处理一些位操作,并且在放入宏和内联函数的同一行代码中遇到奇怪的不同输出。该函数返回64位掩码,该掩码从N
-位置:(~0<<N) - (~0<<(N+L))
中具有L
位活动位。谁能告诉我输出不一样的原因?
#include <iostream>
#include <bitset>
using namespace std;
#define ONES (~0UL)
#define MASK(from_bit, nbits)
(ONES << (from_bit)) - (ONES << ((from_bit) + (nbits)))
inline unsigned long int mask(size_t from_bit, size_t nbits) {
return (ONES << from_bit) - (ONES << (from_bit + nbits));
}
int main(int argc, char **argv) {
cout << "using #define: " << bitset<64>(MASK(63, 3)) << endl;
cout << "using inline function: " << bitset<64>(mask(63, 3)) << endl;
return 0;
}
输出:$ g++ -o test main.cc
main.cc: In function 'int main(int, char**)':
main.cc:15: warning: left shift count >= width of type
$ ./test
using #define: 1000000000000000000000000000000000000000000000000000000000000000
using inline function: 1000000000000000000000000000000000000000000000000000000000000100
------^
使用-O3
选项编译:
$ g++ -O3 -o test2 main2.cc
main.cc: In function 'int main(int, char**)':
main.cc:15: warning: left shift count >= width of type
$ ./test2
using #define: 1000000000000000000000000000000000000000000000000000000000000000
using inline function: 0000000000000000000000000000000000000000000000000000000000000000
------^
编译器信息:$ g++ --version
i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00)
你不应该忽略编译器的警告。它告诉你有问题。
你只能合法地移动少于整数类型的位数
如此:
#include <iostream>
#include <bitset>
using namespace std;
#define ONES (~0ULL)
#define MASK(from_bit, nbits)
(ONES << (from_bit)) - (ONES << (from_bit) << (nbits))
inline unsigned long long mask(unsigned from_bit, unsigned nbits) {
return (ONES << from_bit) - (ONES << from_bit << nbits);
}
int main(int argc, char **argv) {
cout << "using #define: " << bitset<64>(MASK(63, 3)) << endl;
cout << "using inline function: " << bitset<64>(mask(63, 3)) << endl;
return 0;
}
输出(ideone):
using #define: 1000000000000000000000000000000000000000000000000000000000000000
using inline function: 1000000000000000000000000000000000000000000000000000000000000000
你的编译器警告它
你的移动量(from_bit + nbits
)大于你正在使用的字体的大小。
宏和函数的区别在于,前者没有类型检查。
相关文章:
- 为什么在我的函数类型后使用引用运算符 (&) 允许我修改它返回的值?
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 是否有任何建议来统一函数类型限定符并简化可恶的函数类型?
- 关于 C++ 中的函数类型定义
- 用于检测函数类型是否为否的特征
- 函数类型参数的模板参数推导
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- C++无效的函数类型转换
- STL 函数和函数类型与函数指针类型
- 如何将result_of与函数类型定义一起使用
- 将模板(没有规范)传递给 std::thread() 会出现错误:<未解析的重载函数类型>匹配错误
- C++ 编译错误:gnu_printf是无法识别的格式函数类型
- 专门用于"direct"函数类型(与函数指针类型相对)
- 将函数类型作为模板参数传递不会编译
- 通过参数传递 lambda(无函数类型模板)
- 如何在模板参数中分离函数类型返回类型和参数
- 为什么比较函数类型需要指定为模板参数?
- 带有限定符的函数类型定义用例
- 如何声明对函数类型的常量引用
- 非类型模板参数允许各种函数类型?