如何测试目标是否有两个';用C预处理器补全整数?

如何测试目标是否有两个';用C预处理器补全整数?,c,C,有时,C编译器的编译器目标是否有两个整数的补码表示并不重要,让预处理器进行检测可能很有用 由于标准要求limits.h和stdint.h中的MAX/MIN宏是可以在预处理器条件中使用的表达式,我认为 #include <limits.h> #if INT_MIN + INT_MAX == -1 # define HAVE_TWOS_COMPLEMENT 1 #endif #包括 #如果INT_MIN+INT_MAX==-1 #定义有两个补码1 #恩迪夫 因为一个人的补码和符号/幅

有时,C编译器的编译器目标是否有两个整数的补码表示并不重要,让预处理器进行检测可能很有用

由于标准要求
limits.h
stdint.h
中的MAX/MIN宏是可以在预处理器条件中使用的表达式,我认为

#include <limits.h>
#if INT_MIN + INT_MAX == -1
# define HAVE_TWOS_COMPLEMENT 1
#endif
#包括
#如果INT_MIN+INT_MAX==-1
#定义有两个补码1
#恩迪夫

因为一个人的补码和符号/幅度体系结构对于有符号整数具有对称的值范围,所以这是个诀窍。问题是,我是否遗漏了一些东西,或者是否有更好的方法以编译器不可知的方式进行这样的测试?

以2的形式补充,−1被编码为111…111

作为补充,−1被编码为111…110

在符号和大小上,−1编码为100..001

因此,以下检测
int
类型的编码:

#if   (-1 & 3) == 1
    //  The encoding is sign-and-magnitude.
#elif (-1 & 3) == 2
    //  The encoding is one’s complement.
#elif (-1 & 3) == 3
    //  The encoding is two’s complement.
#else
    //  Not possible in the C standard.
#endif

问题中提供的测试,
INT_MIN+INT_MAX==-1
,不可靠,因为C 2018 6.2.6.2 2 2允许“符号位为1且所有值位为零的值”作为陷阱表示,在这种情况下,
INT_MIN
为−(2米−1) ,其中M是值位数,
INT\u MAX
是2M−1,所以
INT\u MIN+INT\u MAX
是零。

好奇的是,你在哪里找到了一台有补码的机器?它们比独角兽更难找到。如果(+0!=-0),你能试试吗?从理论上讲,这应该在一个人的补码上返回真值。像
int32_t
这样的stdint类型的存在意味着它有2的补码整数。另外,下一个版本的C将需要2的补码。@David:嗯,标准允许这样做。所以,可移植代码应该处理它,而非可移植代码应该测试它并抱怨,而不是做奇怪的事情…@Alex:部分。。。e、 我不太相信,例如,测试
-0!=0
在补码或符号上/mag机器按预期工作,因为数字比较按值而不是按位模式,AFAIK。另外,那里的一些测试可能会调用UB来处理整数溢出。但是是的,这个问题本质上是我的一个超集。thnx.@Eric:thnx用于提醒我
0x80…0
可能是陷阱表示。考虑到所有问题,在
-1
上进行位屏蔽似乎是处理该问题的最佳方法。