我要换一个
#define MAX_UINT16 65535
到
#define MAX_UINT16 65535UL
在许多平台上使用的大型图书馆项目中。使用
unsigned long
文字而不是int
文字时,是否有任何行为不同的构造(除了一些警告消失,这就是为什么我要更改它)?(显然,MAX_UINT16没有移位)
我在想像
unsigned long ulvar = read_something_as_unsigned_long();
uint16 ui16var;
if (ulvar > MAX_UINT16) {
display_error("Not in range\n");
ui16var = MAX_UINT16;
} else {
ui16var = ulvar;
}
编辑:当然,不需要
L
,所以当使用65535U
而不是65535
时,它的表现是否有所不同? 最佳答案
使用无符号长文字而不是int文字时,是否有任何行为有所不同的构造(除了一些警告消失,这就是为什么我要更改它)?
这是C11(草稿)标准6.3.1.3(强调我的)中的相关部分:
6.3.1.3有符号和无符号整数
将具有整数类型的值转换为_Bool以外的其他整数类型时,如果该值可以用新类型表示,则该值不变。
否则,如果新类型是无符号的,则通过重复添加或减去比新类型中可以表示的最大值多一个值来转换该值,直到该值在新类型的范围内为止。
否则,将对新类型进行签名,并且无法在其中表示值;结果是实现定义的,还是引发实现定义的信号。
如果在代码中有一点无意中将65535U
分配给一个不能完全保存该值的带符号类型变量,则最终值是实现定义的。因此,将65535U
分配给int16_t
会使用GCC和VC ++生成-1
,但是该结果不能由标准保证,并且取决于编译器的实现。同样,默认情况下,GCC(-Wall
)和VC ++(/W4
)均不发出警告。在GCC中传递-pedantic
可以解决问题。
也就是说,即使此问题继续存在,也应该存在,因为它大于16位带符号2的补码类型可容纳的最大正值。因此,我的建议是继续进行更改。完成后,启用最大警告级别并构建项目以进行验证。