标准C预处理器如何解释“0xFFFFFFFF”?

时间:2013-10-23 02:23:56

标签: c c-preprocessor

标准C预处理器如何解释“0xFFFFFFFF”:4G-1还是-1?

“〜0”的相同问题......

如果答案为-1,那么如何将其解释为4G-1(即除了明确使用4294967295之外还有其他方法吗?)

P.S。:我在MS Visual Studio上尝试过它(使用比较而不是调用'printf',因为后者只是根据指定的'%'打印),答案是4G-1。但我不确定MS Visual Studio是否使用标准C预处理器。

谢谢

4 个答案:

答案 0 :(得分:3)

就预处理器而言,0xFFFFFFFF只是一个十六进制常量。预处理程序表达式中的数字(仅与#if#elif指令相关)被认为是最宽的可用整数类型;预处理器将0xFFFFFFFF视为有符号整数常量,其值为2 32 -1,或4294967295(因为,从C99开始,始终存在整数类型at至少64位)。

如果它出现在#if#elif指令以外的任何位置,则预处理器无关紧要。十六进制常量的类型是第一个:

  • int
  • unsigned int
  • long int
  • unsigned long int
  • long long int
  • unsigned long long int

对于这个特定的常数,有几种可能性:

  • 如果int小于32位且long大于32位,则类型为long;
  • 如果int小于32位且long正好是32位,则类型为unsigned long;
  • 如果int为32位,则类型为unsigned int;
  • 如果int宽于32位,则类型为int

在现代系统中,unsigned intunsigned long是最有可能的。

所有案例中,0xFFFFFFFF的值正好是2 32 -1或4294967295;它从不具有负值。

但是,您可以通过转换(显式或隐式)将-1的值转换为签名类型来轻松获得负值(例如0xFFFFFFFF):< / p>

int n = 0xFFFFFFFF;

但这不便携。如果int宽于32位,则存储的值将为2 32 -1。即使int正好是32位,将无符号值转换为有符号类型的结果也是实现定义的; -1是一个常见的结果,但不能保证。

至于~0,这是一个int表达式,其值的所有位都设置为1 - 通常 -1,但不保证

你究竟想做什么?

答案 1 :(得分:2)

Per C 2011(N1570)6.10.1 4,预处理器中计算的整数表达式使用实现中最宽泛的类型(intmax_tuintmax_t)。 0xFFFFFFFF的值为2 32 -1,因为每个C实现必须支持该值为unsigned long~0在任何正常的C实现中都没有该值。

仅在#if#elif语句的预处理程序中计算表达式。您的问题中的文字表明您正在尝试打印由预处理器评估产生的某些表达式。这不会发生。 #if#elif语句之外的源文本中的常量表达式由常规C规则评估,而不是由预处理器评估。

答案 2 :(得分:1)

ANSI C对各种核心数据类型的大小提供的保证非常少,因此依赖cpp来解释上述某种方式可移植的值是错误的。如果按下,请考虑将其包装在支票中:

#if 0xFFFFFFFF == -1
...
#else
...
#endif

答案 3 :(得分:1)

预处理器在强制执行之前不会解释数字。写

 #define N  0xffffffff
除了预处理器N评估之外,

是使用#if的简单文本替换。 C对价值的作用远比你想要的更有可能。例如,

 long number = N;  // declare and initialize to symbolic value N

这可能会也可能不会导致编译警告,或者可能是错误,具体取决于long的大小以及编译器如何灵活地转换初始化常量。