![](/img/trans.png)
[英]Implicit casting from float to integer in C — why not the other way around?
[英]C: Implicit casting and integer overflowing in the evaluation of expressions
我們來看看代碼
int a, b, c;
...
if ((a + b) > C)
如果我們添加a和b的值並且總和超過int的最大值,那么比較的完整性是否會受到影響? 我當時認為可能存在隱式向上轉換或溢出位檢查,這將被考慮到此表達式的評估中。
C不會做這樣的事情。 它將無聲地溢出並導致可能不正確的比較。 您可以自己升級,但不會自動完成。
測試證實GCC 4.2.3將簡單地與溢出結果進行比較:
#include <stdio.h>
int main()
{
int a, b, c;
a = 2000000000;
b = 2000000000;
c = 2100000000;
printf("%d + %d = %d\n", a, b, a+b);
if ((a + b) > c)
{
printf("%d + %d > %d\n", a, b, c);
}
else
{
printf("%d + %d < %d\n", a, b, c);
}
return 0;
}
顯示以下內容:
2000000000 + 2000000000 = -294967296
2000000000 + 2000000000 < 2100000000
我相信這可能是特定於平台的。 查看有關如何處理溢出的C文檔...
啊,是的,並且上傳不會自動發生......
請參閱K&R書中的第2.7節“ 類型轉換 ”
如果向上轉換沒有獲得任何位(在C中不能保證sizeof(long)> sizeof(int),你可以使用下面的條件進行比較和檢查溢出向上幾乎肯定會更快,如果你能但是,請使用它。
#if !defined(__GNUC__) || __GNUC__<2 || (__GNUC__==2 && __GNUC_MINOR__<96)
# define unlikely(x) (x)
#else
# define unlikely(x) (__extension__ (__builtin_expect(!!(x), 0)))
#endif
/* ----------
* Signed comparison (signed char, short, int, long, long long)
* Checks for overflow off the top end of the range, in which case a+b must
* be >c. If it overflows off the bottom, a+b < everything in the range. */
if(a+b>c || unlikely(a>=0 && b>=0 && unlikely(a+b<0)))
...
/* ----------
* Unsigned comparison (unsigned char, unsigned short, unsigned, etc.)
* Checks to see if the sum wrapped around, since the sum of any two natural
* numbers must be >= both numbers. */
if(a+b>c || unlikely(a+b<a))
...
/* ----------
* To generate code for the above only when necessary: */
if(sizeof(long)>sizeof(int) ? ((long)a+b>c)
: (a+b>c || unlikely(a>=0 && b>=0 && unlikely(a+b<0)))
...
偉大的宏或內聯函數的候選人。 如果你願意,你可以拉出“不太可能”,但它們可以幫助縮小和加速GCC生成的代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.