强制类型转换和sizeof

最近在debug时候遇到一个非常有趣的语法bug。

#define REG_ADDR(x)  ((volatile uint32_t *)(uintptr_t)(HU + OFFSET)

i = i =0x4;

READ(REG + i); //我的本意是想在OFFSET的基础再加 i,这样来读取想要的数值。

但实际结果确实:

printf("OFFSET + i =%x\n", READ(REG + i));

10...20...30...

并不是想要的0...4...8

这是因为i被隐式的类型转换了,转换成(volatile uint32_t),而这种类型每加4就等于加了16个字节。

再来看下((volatile uint32_t *)(uintptr_t)(HU + OFFSET)

这个很奇怪吧?之前每见过这种写法,其实它本质上就是类型转换。

C和指针一书中明确说明了:(类型)被称为强制类型转换(cast)

所以((volatile uint32_t *)(uintptr_t)(HU + OFFSET)就是先转化为(uintptr_t)再转换为(volatile uint32_t *)

也就是说最左边的类型转换就是最终的强制类型转换

在实验的时候还遇到另外一个现象,就是sizeof的返回值类型。

printf("%d\n", sizeof(int));

报错:‘%d’ expects argument of type 'int' but ...'long unsigned int'

说明sizeof的返回值在我这台机器的编译器上是long unsigned。sizeof返回值类型本身是size_t 这个在不同编译器可能不一样。

上一篇:kafka是如何通过offset定位一条消息的?


下一篇:Kafka生产环境问题总结及性能优化实战:JVM参数设置、消息丢失、重复消费、消息乱序、延时队列、消息回溯、分区数量设置、消息传递保障、kafka的事务、kafka高性能的原因