背景
在看开源的相关代码中,会有下面的宏定义用法
#define TEST_VALUE (0xFFFFFFFFU)
其和下面的宏定义区别是什么呢?
#define TEST_VALUE (0xFFFFFFFF)
答疑
U表示 unsigned 无符号后缀,关于后缀的表述C99标准有如下定义:
(1) 没有后缀的情况
10进制和16进制书写立即数,编译器对其解析是有差异的。
对于10进制:始终认为立即数是有符号类型的。
对于16进制:立即数的符号类型取决于其值的大小。具体看立即数是否落在哪个类型区间,即表格中类型:int,unsigned int;long int,unsigned long int ;long long int,unsigned long long int;
(2)有后缀U或u的情况
10进制和16进制书写立即数,编译器对其解析是一致的,始终认为其是无符号类型的
(3)其它情况
略
注:8进制和18进制现象一样,故只表述16进制
验证
(1)没有后缀的情况
10进制:立即数较小VS立即数较大场景对比
测试方法和结果如下:
测试结论:对于10进制立即数,没有后缀的情况下,其进行算术操作后的结果始终是有符号数
16进制:立即数较小VS立即数较大场景对比
测试方法和测试结果如下:
测试结论:对于16进制立即数,没有后缀的情况下,其进行算术操作后的结果始终是有符号数取决于立即数的大小,具体看立即数是否落在哪个类型区间,即表格中类型:int,unsigned int;long int,unsigned long int ;long long int,unsigned long long int。
(2)有后缀的情况
10进制:立即数较小VS立即数较大场景对比
测试方法和结果如下:
测试结论:对于10进制立即数,有后缀的情况下,其进行算术操作后的结果始终是无符号数
16进制:立即数较小VS立即数较大场景对比
测试方法和结果如下:
测试结论:对于16进制立即数,有后缀的情况下,其进行算术操作后的结果始终是无符号数
总结
(1)验证了C标准,关于对立即数符号类型的定义,符合预期。
(2)在C或C++编程的时候,应当对立即数后面加后缀U或L,以明确表示其符合类型。
(3) 避免立即数进行运算的时候,编译器隐含的操作,使得结果不符合预期
(4) 函数重载的时候,能基于明确的参数类型,调用正确的函数
(5) ARM官方ATF Demo源码中,对于C代码编程,关于立即数都会加后缀修饰