将〜操作员更改数据类型?

时间:2013-02-03 07:39:08

标签: c

当我读到某人的代码时,我发现他打算写一个明显的类型演员。

 #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 }

它也有效。它只是一种无意义的编码风格吗?

2 个答案:

答案 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,那么~运算符将应用于它恰好是其他任何类型,其结果将是被投了。

如果编译器确定0shortchar,则会出现问题。

但是, ~运算符后的类型应保持不变。所以他们对外线球员过于谨慎,但也许内心的阵容是合理的。

他们当然可以通过编写~0UL来指定正确的零类型。