在编写代码时,我在代码中观察到一件事,它与比特字段值与负整数的比较有关.
我有一个大小为1位的无符号结构成员和一个unsigned int.当我将负值与unsigned int变量进行比较时,我得到预期的结果为1但是当我将结构成员与负值进行比较时,我得到的结果相反为0.
#include <stdio.h>
struct S0
{
unsigned int bit : 1;
};
struct S0 s;
int main (void)
{
int negVal = -3;
unsigned int p = 123;
printf ("%d\n", (negVal > p)); /*Result as 1 */
printf ("%d\n", (negVal > s.bit));/*Result as 0 but expected 1 */
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我怀疑的是,如果我将负值与unsigned int进行比较,那么将发生平衡(隐式类型转换).但是如果我比较unsigned int的结构成员为什么没有发生隐式类型转换.如果我错过任何基本的比特字段,请纠正我?
(把我的评论作为答案)
GCC促进s.bit到INT,所以(negVal > s.bit)不(-3 > 0)重视0
请参阅大小小于int的位字段是否应该是整体提升的主题?但你的问题并不重复.
(negVal > p)返回1因为negVal被提升为unsigned而产生一个大值,请参阅Signed/unsigned比较
为了便于说明,下面使用 32 位int和 32 位unsigned int.
在negVal > p:
negVal是一个int值为 \xe2\x88\x923 的值。p值为unsigned int123。>其他关系运算符,告诉我们通常的算术转换是在操作数上执行的。int、unsigned int、 和比这些更宽的整数类型保持不变。对于其他整数类型,它表示: \xe2\x80\x9d 如果 anint可以表示原始类型的所有值(对于位字段,受宽度限制),则该值将转换为int; 否则,它会转换为unsigned int.\xe2\x80\x9dnegVal是 an int,因此整数提升不会改变它。p是 an unsigned int,因此整数提升不会改变它。int和unsigned int, 被int转换为unsigned int。int将\xe2\x88\x923转换为unsigned int结果 4,294,967,293。(转换定义为UINT_MAX + 1根据需要对值进行多次加或减,即 4,294,967,296,使其处于范围内。这相当于 \xe2\x80\x9cwrapping\xe2\x80\x9d 模 4,294,967,296 或重新解释\xe2\x80\x99s 将 \xe2\x88\x923 的两个补码表示为unsigned int。)negVal > p变为4294967293u > 123u。在negVal > s.bit:
negVal是一个int值为 \xe2\x88\x923 的值。s.bit是一个值为 0 的一位位域。negVal是 an int,因此整数提升不会改变它。s.bit是 比 an 窄的位域int,因此它将通过整数提升进行转换。这个一位位域可以表示 0 或 1。这两者都可以用 来表示int,因此规则 \xe2\x80\x9cIf anint可以表示原始类型的所有值(受宽度限制,对于位字段),该值被转换为int\xe2\x80\x9d 应用。int0。int,因此不需要转换。negVal > s.bit变为-3 > 0。