4

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

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

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

PS:我在MS Visual Studio上试了一下(当然是使用比较而不是调用'printf',因为后者会简单地根据指定的'%'打印),答案是4G-1。但我不确定 MS Visual Studio 是否使用标准的 C 预处理器。

谢谢

4

4 回答 4

3

As far as the preprocessor is concerned, 0xFFFFFFFF is just a hexadecimal constant. Numbers in preprocessor expressions (which are relevant only in #if and #elif directives) are taken to be of the widest available integer type; the preprocessor will treat 0xFFFFFFFF as a signed integer constant with the value 232-1, or 4294967295 (since, as of C99, there is always an integer type of at least 64 bits).

If it appears anywhere other than a #if or #elif directive, then the preprocessor is irrelevant. A hexadecimal constant's type is the first of:

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

For this particular constant, there are several possibilities:

  • If int is narrower than 32 bits and long is wider than 32 bits, then the type is long;
  • If int is narrower than 32 bits and long is exactly 32 bits, then the type is unsigned long;
  • If int is 32 bits, then the type is unsigned int;
  • If int is wider than 32 bits, then the type is int.

On modern systems, unsigned int and unsigned long are the most likely possibilities.

In all cases, the value of 0xFFFFFFFF is exactly 232-1, or 4294967295; it never has a negative value.

However, you can easily get a negative value (say, -1) by converting (either explicitly or implicitly) the value of 0xFFFFFFFF to a signed type:

int n = 0xFFFFFFFF;

But this is not portable. If int is wider than 32 bits, the stored value will be 232-1. And even if int is exactly 32 bits, the result of converting an unsigned value to a signed type is implementation-defined; -1 is a common result, but it's not guaranteed.

As for ~0, that's an int expression whose value has all its bits set to 1 -- which is usually -1, but that's not guaranteed.

What exactly are you trying to do?

于 2013-10-23T03:26:54.867 回答
2

根据 C 2011 (N1570) 6.10.1 4,在预处理器中评估的整数表达式使用实现中最宽的类型 (intmax_tuintmax_t)。0xFFFFFFFF将具有值 2 32 -1 因为每个 C 实现都必须支持该值作为unsigned long. ~0在任何正常的 C 实现中都不会具有该值。

表达式仅在预处理器中为#ifand#elif语句求值。您问题中的文字表明您正在尝试打印一些由预处理器评估产生的表达式。那不会发生。#if和语句之外的源文本中的常量表达式#elif由常规 C 规则评估,而不是由预处理器评估。

于 2013-10-23T02:47:46.287 回答
1

ANSI C 对各种核心数据类型的大小几乎没有保证,因此依赖于cpp以一种或另一种方式解释上述值一个错误。如果按下,请考虑将其包装在检查中:

#if 0xFFFFFFFF == -1
...
#else
...
#endif
于 2013-10-23T02:27:07.833 回答
1

预处理器在被迫解释数字之前不会解释数字。写作

 #define N  0xffffffff

在任何使用的地方都是简单的文本替换N,除了预处理器#if评估。C 对值所做的事情更有可能是您想要询问的内容。例如,

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

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

于 2013-10-23T02:29:06.693 回答