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