英文:
Why isn’t implicit type conversion happening from unsigned short int to signed char?
问题
Output: a is small
在代码2中,unsigned short int
(第4行)大于signed char
(第3行),为什么不发生隐式转换?
或者
为什么unsigned short int
和signed char
的隐式转换没有发生?
请注意,我已经按照您的要求,只返回翻译好的部分。
英文:
code 1:
#include <stdio.h>
int main()
{
short int a = -1; // ----> Line 1
unsigned int b = 122; // ----> Line 2
if (a > b)
printf("a is big");
else
printf("a is small");
return 0;
}
Output: a is big
Since here the Line 1 is implicitly converted to Line 2, ie: signed short int
to unsigned int
.
similarly
code 2:
#include <stdio.h>
int main()
{
char a = -1; // ---> Line 3
unsigned short int b = 122; // ---> Line 4
if (a > b)
printf("a is big");
else
printf("a is small");
return 0;
}
Output: a is small
Here in code 2, since unsigned short int
(Line 4) is greater than signed char
(Line 3), why is the implicit conversion not happening?
or
Why doesn't the implicit conversion for unsigned short int
and signed char
take place?
答案1
得分: 2
This little riddle hides a difficult problem: integer promotions may behave differently on different systems, depending on the size of types char
, short
, and int
.
When an operation is evaluated between types that have a rank lesser or equal to that of int
, integer promotions are performed and the operation is evaluated on the resulting type, int
or unsigned int
depending on the original types.
If both types are smaller (have fewer value bits) than int
, they are promoted to int
, which preserves the value. If one or both have the same number of value bits as unsigned int
, they are both promoted to unsigned int
, which changes negative values to large positive ones.
In addition to this difficulty, you are storing the value -1
to a variable of type char
. Depending on the signedness of type char
, the value -1
may be converted to the positive value UCHAR_MAX
. This is the case if type char
is unsigned.
Let's investigate your examples:
code 1:
short int a = -1; // Line 1
unsigned int b = 122; // Line 2
short int
a
is promoted to unsigned int
, the type of b
, and the value -1
changes to UINT_MAX
, which is much larger than 122
, hence the comparison is true, a is big
. This behavior does not depend on the architecture.
code 2:
char a = -1; // Line 3
unsigned short int b = 122; // Line 4
-
if
char
is signed,a
has the value-1
, but ifchar
is unsigned,a
would have the valueUCHAR_MAX
, which is255
on architectures with 8-bit bytes. -
if type
unsigned short int
has the same size asunsigned int
(16-bit architectures), both values are promoted tounsigned int
(-1
becomesUINT_MAX
) and the comparison is eitherUINT_MAX > 122
or255 > 122
, which is true in both cases. -
if type
unsigned short int
is smaller thanint
, both values are promoted toint
and the comparison is either-1 > 122
or255 > 122
, which depends on the signedness of typechar
.
Your system outputs a is small
, which means char
is signed, and short
has fewer bits than int
, so the comparison is -1 > 122
, which is false.
英文:
This little riddle hides a difficult problem: integer promotions may behave differently on different systems, depending on the size of types char
, short
and int
.
When an operation is evaluated between types that have a rank lesser or equal to that of int
, integer promotions are performed and the operation is evaluated on the resulting type, int
or unsigned int
depending on the original types.
If both types are smaller (have fewer value bits) than int
, they are promoted to int
, which preserves the value. If one or both have the same number of value bits as unsigned int
, they are both promoted to unsigned int
, which changes negative values to large positive ones.
In addition to this difficulty, you are storing the value -1
to a variable of type char
. Depending on the signedness of type char
, the value -1
may be converted to the positive value UCHAR_MAX
. This is the case if type char
is unsigned.
Let's investigate your examples:
code 1:
short int a = -1; // ----> Line 1
unsigned int b = 122; // ----> Line 2
short int
a
is promoted to unsigned int
, the type of b
and the value -1
changes to UINT_MAX
, which is much larger than 122
, hence the comparison is true, a is big
. This behavior does not depend on the architecture.
code 2:
char a = -1; // ---> Line 3
unsigned short int b = 122; // ---> Line 4
-
if
char
is signed,a
has the value-1
, but ifchar
is unsigned,a
would have the valueUCHAR_MAX
, which is255
on architectures with 8-bit bytes. -
if type
unsigned short int
has the same size asunsigned int
(16-bit architectures), both values are promoted tounsigned int
(-1
becomesUINT_MAX
) and the comparison is eitherUINT_MAX > 122
or255 > 122
, which is true in both cases. -
if type
unsigned short int
is smaller thanint
, both values are promoted toint
and the comparison is either-1 > 122
or255 > 122
, which depends on the signedness of typechar
.
Your system outputs a is small
, which means char
is signed and short
has fewer bits than int
, so the comparison is -1 > 122
, which is false.
答案2
得分: 1
char
、signed char
、unsigned char
、short
和 unsigned short
从不被视为整数提升的结果类型。
整数提升起源于早期的C开发,那时算术运算主要使用本地处理器寄存器以其普通宽度进行,而char
和short
是用于存储数据的类型。int
类型被用作处理器上的“自然”类型,与其寄存器匹配。因此,char
和short
数据被加载到处理器寄存器中,然后使用实际上执行int
算术的指令进行操作。当前的标准C规则反映了这一历史;整数提升将整数类型提升至至少int
或unsigned int
。
在您的C实现中,unsigned short int
比int
窄,因此它被提升为int
。char
也是如此。因此,char
值-1被提升为int
,产生了一个值为-1的int
值,而unsigned short int
值为122被提升为int
,产生了一个值为122的int
值,然后这些值被比较。然后-1不大于122,所以a > b
评估为假。
通常的算术转换的具体规则如下:
-
如果其中一个操作数(或者如果是复数,则是其相应的实际类型)是
long double
,则将另一个操作数转换为long double
。 -
否则,如果其中一个操作数(或者如果是复数,则是其相应的实际类型)是
double
,则将另一个操作数转换为double
。 -
否则,如果其中一个操作数(或者如果是复数,则是其相应的实际类型)是
float
,则将另一个操作数转换为float
。 -
否则,整数提升将在两个操作数上执行:具有整数转换等级低于
int
的类型的值,如果int
可以表示源类型的所有值(例如,如果unsigned short
的宽度与int
相同,则具有int
无法表示的一些值),否则转换为unsigned int
。(具有较高等级的类型不会转换。)具有_Bool
、int
或unsigned int
位字段类型的值也以这种方式转换。 -
如果两个结果操作数具有相同的类型,则不执行进一步的转换。
-
否则,如果两者具有有符号类型或都具有无符号类型,则将具有较低等级的操作数转换为另一种类型。
-
否则,如果无符号类型的等级至少等于有符号类型的等级,则将有符号类型转换为无符号类型。
-
否则,如果有符号类型可以表示无符号类型的所有值,则将无符号类型转换为有符号类型。
-
否则,两个操作数都将转换为与有符号类型对应的无符号类型。(例如,如果操作数是
unsigned short
和int
,它们具有相同的宽度,它们将被转换为unsigned int
。)
英文:
char
, signed char
, unsigned char
, short
, and unsigned short
are never considered as result types of the integer promotions.
The integer promotions originated in early C development where arithmetic was largely done using the native processor registers in their ordinary widths, and char
and short
were types used for storing data. The int
type was used as the “natural” type on the processor, matching its registers. So char
and short
data was loaded into processor registers and then operated on with, in effect, instructions that performed int
arithmetic. The current rules of standard C reflect this history; the integer promotions bring integer types up to at least int
or unsigned int
.
In your C implementation, unsigned short int
is narrower than int
, so it is promoted to int
. So is char
. Thus the char
value −1 is promoted to int
, yielding an int
value of −1, and the unsigned short int
value of 122 is promoted to int
, yielding an int
value of 122, and these are compared. Then −1 is not greater than 122, so a > b
evaluates as false.
The specific rules for the usual arithmetic conversions are:
-
If either operand (or, if complex, its corresponding real type) is
long double
, the other operand is converted tolong double
. -
Otherwise, if either operand (or, if complex, its corresponding real type) is
double
, the other operand is converted todouble
. -
Otherwise, if either operand (or, if complex, its corresponding real type) is
float
, the other operand is converted tofloat
. -
Otherwise, the integer promotions are performed on both operands: A value with a type with integer conversion rank less than
int
is converted toint
ifint
can represent all values of the source type (for example, ifunsigned short
is the same width asint
, it has some values thatint
cannot represent) or tounsigned int
otherwise. (Values with a type with greater rank are not converted.) Values with bit-field types of_Bool
,int
orunsigned int
are also converted in this way. -
If both resulting operands have the same type, no further conversion is performed.
-
Otherwise, if both have signed type or both have unsigned type, the operand with lower rank is converted to the other type.
-
Otherwise, if rank of the unsigned type is at least the rank of the signed type, the signed type is converted to the unsigned type.
-
Otherwise, if the signed type can represent all the values of the unsigned type, the unsigned type is converted to the signed type.
-
Otherwise, both operands are converted to the unsigned type corresponding to the signed type. (For example, if the operands are
unsigned short
andint
, and those have the same width, they will be converted tounsigned int
.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论