意外的宏计算
Unexpected macro evaluation
为什么这是ffffffff
?
#define MYMACRO(n) (((uint16_t)0 - 1) >> (16 - (n)))
std::cout << std::hex << MYMACRO(1);
同时打印1
?
#define MYMACRO(n) (((uint32_t)0 - 1) >> (32 - (n)))
std::cout << std::hex << MYMACRO(1);
我用GCC和cpp.sh试过了
说明在type-promotion-in-c.
(§6.3.1.1布尔值、字符和整数):
如果int型可以表示原类型的所有值,则将该值转换为int型;…这些被称为整数提升。所有其他类型都不受整数提升的影响。
因此,对于第一种情况,((uint16_t)0 - 1)
被转换为int
以满足减法的需要。因此右移操作是算术右移,而不是逻辑右移。
c++中有积分提升。尽管如此,实际测试表达式并不是一个坏主意,以了解幕后发生了什么…
#include <typeinfo>
#include <iostream>
#include <boost/type_index.hpp>
using namespace std;
int main(){
#define MYMACRO(n) (((uint16_t)0 - 1) >> (16 - (n)))
std::cout << std::hex << MYMACRO(1);
std::cout << "n-----n";
#undef MYMACRO
#define MYMACRO(n) (((uint32_t)0 - 1) >> (32 - (n)))
std::cout << std::hex << MYMACRO(1);
std::cout << "n--++++--n";
std::cout << boost::typeindex::type_id<decltype((uint16_t)0)>().pretty_name() << std::endl;
std::cout << boost::typeindex::type_id<decltype((uint16_t)0 - 1)>().pretty_name() << std::endl;
std::cout << boost::typeindex::type_id<decltype((uint32_t)0 - 1)>().pretty_name() << std::endl;
}
移位运算符后的整数类型在本例中不相关。从上面程序的输出中可以看到Live On Coliru
ffffffff
-----
1
--++++--
unsigned short
int
unsigned int
总结:
子表达式:
(uint16_t)0
产生unsigned short
,在大多数平台上通常表达式:
(uint16_t)0 - 1
产生int
类型;因为整数提升规则。1
是类型为int
的整型常数表达式:
(uint32_t)0 - 1)
产生unsigned int
类型;仍然是因为通常的算术转换。unsigned int
被认为大于int
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- 如何计算文件中的"columns"数?
- 计算排序向量的向量中唯一值的计数
- 在C++中对T*类型执行std::move的意外行为
- 如何使用 std::累积在 C++ 中计算总和立方体
- 使用Qt C++计算类似Git的SHA1哈希
- OpenCV C++.快速计算混淆矩阵
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- C++如何计算用户输入的数字中的偶数位数
- 如何计算数据类型的范围,例如int
- 递归函数用于计算 n 个数字之和的意外输出
- 计算导致意外的0
- C++ 程序中的意外计算
- C++枚举的计算结果为意外值
- 意外的宏计算
- 在计算环形总数时出现意外结果