我要换一个

#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的补码类型可容纳的最大正值。因此,我的建议是继续进行更改。完成后,启用最大警告级别并构建项目以进行验证。

10-04 19:51