Re: [问题] 十三诫之七的疑问

楼主: tinlans ( )   2016-04-16 15:25:19
先定位一下你的问题。
1. 比较运算式隶属于运算式 (expression) 的一种,所以规格书查 6.5 Expressions。
2. 这种运算式用的运算子被标准称为关系运算子 (relational operators),
所以应该要查 6.5.8 Relational operators。
打开 6.5.8 的 paragraph 3,劈面就看到一段:
If both of the operands have arithmetic type, the usual arithmetic conversions
are performed.
那什么叫 usual arithmetic conversion?
这个看目录就找得到了,就是 6.3.1.8 Usual arithmetic conversions。
你的问题跟浮点数无关,所以上面那堆有的没的跳过,直接从这开始看:
Otherwise, the integer promotions are performed on both operands.
Then the following rules are applied to the promoted operands:
If ...
Otherwise, ...
Otherwise, ...
Otherwise, ...
简单讲就是 integer promotion 要先分别施加于运算子两边的算子,
等做完以后才开始去下面的 if ... else if ... else if ... else ... 判断。
在这一大串判断条件里会看到 integer promotion 和 integer conversion rank,
所以接下来的关键就是要了解这两个东西到底是什么。
先去查什么叫 integer promotion,会突然冒出这名词通常都是前面已经提过。
往上卷几页,回到 6.5 Conversions 开头的后面一页,可以看到:
The following may be used in an expression wherever an int or unsigned int may
be used:
- An object or ...
- A bit-field ...
If an int can represent all values of the original type (as restricted by the
width, for a bit-field), the value is converted to an int; otherwise, it is
converted to an unsigned int. These are called the integer promotions.) All
other types are unchanged by the integer promotions.
这段话是在讲什么?
是在讲如果 int 或 unsigned int 出现在运算式中,同时另一边是比它小的 type,
符合这样的条件就会实施 integer promotion,是给 int 专用的帝王条款。
你的问题一边是 int,另一边 unsigned int,所以跟 integer promotion 完全无关。
所以再来就是了解什么叫 integer conversion rank。
拉到上一页 6.3.1.1 Boolean, characters, and integers 马上就会看到 :
Every integer type has an integer conversion rank defined as follows:
- No two signed integer types shall have the same rank, even if they have
the same representation.
- The rank of a signed integer type shall be greater than the rank of any
signed integer type with less precision.
- The rank of long long int shall be greater than the rank of long int,
which shall be greater than the rank of int, which shall be greater than
the rank of short int, which shall be greater than the rank of signed
char.
上面这三条只是想说 long long > long > int > short > signed char,
就算 sizeof(long) == sizeof(int) 也不会导致它们 rank 一样。
- The rank of any unsigned integer type shall equal the rank of the
corresponding signed integer type, if any.
这是在说:
1. 同 type 的 signed 及 unsigned 版本有相同 rank。
2. 因此 signed 的那套不等式同样施加于 unsigned。
你的问题就是要看这一条,下面的那些跟问题无关就不贴了。
接下来就回到 usual arithmetic conversion,也就是这些东西:
If both operands have the same type, then no further conversion is needed.
Otherwise, if both operands have signed integer types or both have unsigned
integer types, the operand with the type of lesser integer conversion rank
is converted to the type of the operand with greater rank.
Otherwise, if the operand that has unsigned integer type has rank greater
or equal to the rank of the type of the other operand, then the operand with
signed integer type is converted to the type of the operand with unsigned
integer type.
Otherwise, if the type of the operand with signed integer type can represent
all of the values of the type of the operand with unsigned integer type, then
the operand with unsigned integer type is converted to the type of the
operand with signed integer type.
Otherwise, both operands are converted to the unsigned integer type
corresponding to the type of the operand with signed integer type.
你这个 unsigned int v.s. signed int 的状况适用第二条,所以结论是变成 unsigned。
原因很简单,因为两边 rank 相同,所以就转换成 unsigned int。
很多人以为这个 case 是晋升 (promotion),实际上这叫转换,不是晋升。
搞错名词的定义会让人连规格书都不知道怎么查,甚至查错,这现象不是很好。
上面这一大片虽然我不解释,但原则上标准规格书偏好 unsigned,不爱 signed。
所以大原则就是如果可能就尽量往 unsigned 转,真没办法才转成 signed。
因为不只是比较运算会用到这些转换规则,一般算术运算也会用到。
C 语言标准依据历代各电脑架构的特性,unsigned integer 被定义成不会 overflow,
换句话说 unsigned int 的极大值 + 1 会变成 0 这行为是 well-defined。
但历史上的某些电脑并非 2 补数系统,典型的例子就是出现过有正负 0 表示法。
虽然现在 2 补数的系统确实负极小 - 1 就会变成正极大,但 C 语言从没说这是对的。
如果系统采用符号大小表示法,这系统非环形,负极小 - 1 是不会绕到正极大的。
因此对 signed integer 运算是会 overflow 的,而且计算结果不一定是多少。
所以为了让运算结果尽可能地变成可预期,标准规格书会比较偏好于转换成 unsigned。
往这方向去理解的话,上面那一串也不用特别去背,这不是填鸭教育,请用理解的。
作者: LiloHuang (十年一刻)   2016-04-16 15:45:00
实际上是转换不是晋升 +1
作者: descent (“雄辩是银,沉默是金”)   2016-04-16 16:24:00
真详细
作者: wtchen (没有存在感的人)   2016-04-16 16:42:00
受教了...所以13诫之7"会提升 int 为 unsigned"是不是该改改?改成"转换"?
作者: coal511464 (我一个人)   2016-04-16 21:50:00
作者: lsc36 (lsc36)   2016-04-16 22:05:00
作者: BlazarArc (Midnight Sun)   2016-04-16 22:35:00
作者: FRAXIS (喔喔)   2016-04-16 23:30:00

Links booklink

Contact Us: admin [ a t ] ucptt.com