C - 类型陷阱¶
陷阱¶
-
有如下这段代码:
typedef struct length_type_data_t { uint8_t length; uint8_t type; uint8_t data[0]; } __attribute__((packed)) length_type_data_t; int main() { int len = 0; printf("diff: %ld\n", len - sizeof(length_type_data_t)); for(int pos = 0; pos < ( len - sizeof(length_type_data_t) ) ;){ printf("Enter loop!\n"); break; } return 0; }
-
::: warning 问题
在上面这段代码中,打印了diff: -2
, 那么请问是否会进入for循环,打印Enter loop!
呢?
:::
-
答案是**会**进入for循环。而我们预期的运行结果是不进入for循环,即便我们把pos的类型改成了uint32_t类型,也还是会进入for循环。
-
证明了编译器把
( len - sizeof(length_type_data_t) )
隐式转换成了Unsigned类型,导致最后的值不是-2
. -
解决办法有如下两种:
- 方法1:
- 方法2:
- 推荐用第二种方法,不要在for里面计算复杂的表达式。
扩展¶
- 如果有如下代码如下所示。是否还会进入for循环呢?
总结¶
- 一定要小心类型的隐式转换和溢出的问题。
- for循环中的大小比较的类型一定要是相同的,不一样的类型会造成预想不到的后果。