0

当我阅读某人的代码时,我发现他费心编写显式类型转换。

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

它也可以。它只是一种毫无意义的编码风格吗?

4

2 回答 2

3

您阅读的代码非常糟糕,有几个原因。

  • 首先,用户代码不应该定义ULONG_MAX. 这是一个保留标识符,必须由编译器实现提供。

  • 该定义不适合在预处理器中使用#if。基本整数类型的_MAX必须在那里可用。

  • (unsigned long)0只是废话。每个人都应该使用0UL,除非您知道您的编译器在这方面不符合所有最新的 C 标准。(我不知道。)

  • Even~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它是无符号的,因此是类型的最大值。但是这个技巧只有在强制转换包含单个标识符标记时才有效,而不是在你的示例中它有三个,并且如果整数常量有一个-+符号。

于 2013-02-03T08:07:57.767 回答
0

他们试图确保值的类型0unsigned long. 当您将零分配给变量时,它会被强制转换为适当的类型。

在这种情况下,如果0不碰巧是 anunsigned long那么该~运算符将应用于它碰巧是的任何其他类型,并且其结果将被强制转换。

0如果编译器决定它是 ashort或,这将是一个问题char

但是,运算符后面的类型~应该保持不变。所以他们对外部演员过于谨慎,但也许内部演员是合理的。

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

于 2013-02-03T07:50:07.680 回答