标准 C 预处理器如何解释“0xFFFFFFFF”:4G-1 或 -1?
“〜0”的同样问题......
如果答案是-1,那么我如何让它解释为4G-1(即,除了明确使用4294967295之外还有其他方法吗)?
PS:我在MS Visual Studio上试了一下(当然是使用比较而不是调用'printf',因为后者会简单地根据指定的'%'打印),答案是4G-1。但我不确定 MS Visual Studio 是否使用标准的 C 预处理器。
谢谢
标准 C 预处理器如何解释“0xFFFFFFFF”:4G-1 或 -1?
“〜0”的同样问题......
如果答案是-1,那么我如何让它解释为4G-1(即,除了明确使用4294967295之外还有其他方法吗)?
PS:我在MS Visual Studio上试了一下(当然是使用比较而不是调用'printf',因为后者会简单地根据指定的'%'打印),答案是4G-1。但我不确定 MS Visual Studio 是否使用标准的 C 预处理器。
谢谢
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:
int
is narrower than 32 bits and long
is wider than 32 bits, then the type is long
;int
is narrower than 32 bits and long
is exactly 32 bits, then the type is unsigned long
;int
is 32 bits, then the type is unsigned int
;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?
根据 C 2011 (N1570) 6.10.1 4,在预处理器中评估的整数表达式使用实现中最宽的类型 (intmax_t
和uintmax_t
)。0xFFFFFFFF
将具有值 2 32 -1 因为每个 C 实现都必须支持该值作为unsigned long
. ~0
在任何正常的 C 实现中都不会具有该值。
表达式仅在预处理器中为#if
and#elif
语句求值。您问题中的文字表明您正在尝试打印一些由预处理器评估产生的表达式。那不会发生。#if
和语句之外的源文本中的常量表达式#elif
由常规 C 规则评估,而不是由预处理器评估。
ANSI C 对各种核心数据类型的大小几乎没有保证,因此依赖于cpp
以一种或另一种方式解释上述值是一个错误。如果按下,请考虑将其包装在检查中:
#if 0xFFFFFFFF == -1
...
#else
...
#endif
预处理器在被迫解释数字之前不会解释数字。写作
#define N 0xffffffff
在任何使用的地方都是简单的文本替换N
,除了预处理器#if
评估。C 对值所做的事情更有可能是您想要询问的内容。例如,
long number = N; // declare and initialize to symbolic value N
这可能会也可能不会导致编译警告,或者可能是错误,具体取决于 a 的大小long
以及编译器转换初始化常量的灵活程度。