因此,如果我乘以兩個值: emacs -batch -eval'(print(* 1252463 -4400000000000))' 它會超過大多數負數 - fixnum框架並將返回數學錯誤的答案。 -O2標誌,-O2 -fsanitize =未定義標誌和-O2 -fwrapv標誌之間的指令級別差異是什麼?當使用emacs lisp時,如果數值超過最大負數
0
A
回答
2
在emacs中?可能沒什麼。這可能是編譯的功能如下:
int multiply(int x, int y) {
return x * y;
}
如果我們編譯,並期待在組件(gcc -S multiply.c && cat multiply.s
),我們得到
multiply:
pushq %rbp
movq %rsp, %rbp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl -4(%rbp), %eax
imull -8(%rbp), %eax
popq %rbp
ret
見imull
指令?它正在進行有規律的繁殖。如果我們嘗試gcc -O2 -S multiply.c
怎麼辦?
multiply:
movl %edi, %eax
imull %esi, %eax
ret
嗯,這的確刪除了一些代碼,但它仍然在做imull
,一個普通乘法。
讓我們試着去得到它不使用imull
:
int multiply(int x) {
return x * 2;
}
隨着gcc -O2 -S multiply.c
,我們得到
multiply:
leal (%rdi,%rdi), %eax
ret
而是計算較慢x * 2
的,它不是計算x + x
,因爲除了比速度更快乘法。
我們可以得到-fwrapv
來產生不同的代碼嗎?是:
int multiply(int x) {
return x * 2 < 0;
}
隨着gcc -O2 -S multiply.c
,我們得到
multiply:
movl %edi, %eax
shrl $31, %eax
ret
所以簡化爲x >> 31
,這是同樣的事情x < 0
。在數學中,如果x * 2 < 0
然後x < 0
。但在處理器的實際情況中,如果x * 2
溢出,則可能會變爲負值,例如2,000,000,000 * 2 = -294967296
。
如果強制GCC考慮到這與gcc -O2 -fwrapv -S temp.c
,我們得到
multiply:
leal (%rdi,%rdi), %eax
shrl $31, %eax
ret
因此,優化x * 2 < 0
到x + x < 0
。將-fwrapv
設置爲默認值可能看起來很奇怪,但是C是在這種可預測的方式溢出標準之前創建的。
相關問題
- 1. 記錄數超過最大整數值
- 2. 使用負數查找最大值
- 3. 超過最大許可數
- 4. 函數超過最大執行時間
- 5. 當所有超時參數設置爲最大值時,WCF服務超時
- 6. 在Emacs Lisp中轉發函數時超出了評估深度
- 7. Emacs Lisp:嵌套在ibuffer中超過`max-lisp-eval-depth'
- 8. Geom_smooth:添加組時,迭代次數超過最大值50?
- 9. 當有最小值和最大值時,用函數in.txt文件寫出結果?
- 10. 當值超過最小值或最大值時,WP7 ProgressBar會中斷
- 11. 當你增加一個整數超過其最大值時會發生什麼?
- 12. angularjs $超時最大值
- 13. ,如果我超過了最大餅乾
- 14. Python「如果超過最大步數,打破循環」
- 15. C編程 - 數組中的最大步數顯示超過最大值
- 16. 如何在超過最大值時使進度條崩潰
- 17. 錯誤:數組大小超過了允許的最大值(1073741823)
- 18. 超過100%給出負數
- 19. ActiveResource超時的最大值
- 20. 超過R中DLL的最大數量
- 21. 當超過最大緩存大小時想知道數據庫行爲
- 22. 使用到最大值的JTextField的DocumentFilter自動設置,如果發現價值超過最大
- 23. 繪製超出軸最大值的數據點,最大值爲
- 24. ORA-0020:超過最大進程數(150)
- 25. 超過最大執行時間的大型數據集
- 26. 如何在emacs lisp函數中搜索
- 27. 如何從另一個Emacs Lisp函數調用具有前綴參數的交互式Emacs Lisp函數?
- 28. 在emacs lisp中訪問字節超出最正面的修復數字
- 29. 如何使用emacs lisp調用Windows API函數?
- 30. 如何通過desc命令,如果我有一個最大值超過一個最大值的表?
如果使用-fsanitize = undefined標誌,你知道會發生什麼嗎?因爲它拋出了未定義的外部函數__ubsan_handle_overflow,並且不會執行。 – Tony
聽起來像你安裝了clang錯誤,'-fsanitize = undefined'對我來說工作正常。嘗試重新安裝? 它應該輸出一個錯誤消息,如'multiply.c:3:14:運行時錯誤:有符號整數溢出:2000000000 * 2不能用'int'類型表示。我非常懷疑,如果使用'-fsanitize = undefined'編譯emacs,它會正常運行,人們總是依賴未定義的行爲。 –