当我读到某人的代码时,我发现他打算写一个明显的类型演员。
#define ULONG_MAX ((unsigned long int) ~(unsigned long int) 0)
当我编写代码时
1 #include<stdio.h>
2 int main(void)
3 {
4 unsigned long int max;
5 max = ~(unsigned long int)0;
6 printf("%lx",max);
7 return 0;
8 }
它也有效。它只是一种无意义的编码风格吗?
答案 0 :(得分:3)
由于多种原因,您阅读的代码非常糟糕。
首先,用户代码永远不应该定义ULONG_MAX
。这是一个保留标识符,必须由编译器实现提供。
该定义不适合在预处理器#if
中使用。基本整数类型的_MAX
宏必须才能在那里使用。
(unsigned long)0
只是废话。每个人都应该使用0UL
,除非你知道你的编译器在这方面不符合所有最新的C标准。 (我不知道。)
即使~0UL
也不应该用于该值,因为unsigned long
可能(理论上)具有填充位。 -1UL
更合适,因为它不处理值的位模式。它使用无符号整数类型的保证算术属性。 -1
始终是无符号类型的最大值。因此,~
只能在您绝对确定unsigned long
没有填充位的上下文中使用。但就这样使用它毫无意义。 -1
提供更好的服务。
正如您所观察到的那样,“重铸”已知为unsigned long
的表达式是多余的。我无法想象任何编译器会对此产生错误。
重新表达可能在预处理器中使用它们时有意义,但仅在非常有限的情况下,并且它们的解释方式不同。
#if ((uintmax_t)-1UL) == SOMETHING
..
#endif
此处左侧的值在后续编译器阶段中预处理器和中的UINTMAX_MAX
值。所以
#define UINTMAX_MAX ((uintmax_t)-1UL)
将是编译器实现的适当定义。
要查看预处理器的值,请注意(uintmax_t)
内的()
不是强制转换,而是0
内的未知标识符令牌,并且它的计算结果为0-1UL
。然后减号被解释为二进制减号,因此我们-
是无符号的,因此是该类型的最大值。但是这个技巧只有在演员表包含一个标识符标记时才有效,而不是如果你的例子中有三个标识符标记,并且整数常量有一个+
或{{1}}标志。
答案 1 :(得分:0)
他们正在尝试确保值0
的类型为unsigned long
。当您为变量赋值为零时,它会被转换为适当的类型。
在这种情况下,如果0
恰好不是unsigned long
,那么~
运算符将应用于它恰好是其他任何类型,其结果将是被投了。
如果编译器确定0
是short
或char
,则会出现问题。
但是, ~
运算符后的类型应保持不变。所以他们对外线球员过于谨慎,但也许内心的阵容是合理的。
他们当然可以通过编写~0UL
来指定正确的零类型。