簡體   English   中英

這個 Visual Studio 編譯器錯誤“除以或除以零”是一個錯誤嗎?

[英]Is this Visual Studio compiler error 'divide or mod by zero' a bug?

我在 Visual Studio 2019 上,當我嘗試編譯時:

#include <iostream>

int main() {
    (-2147483647 - 1) / -1;
    INT_MIN / -1;
}

在這兩種情況下我都會遇到編譯器錯誤:

C2124 'divide or mod by zero'

據我所知,沒有除以零或除以零。

通過提高警告級別,編譯器揭示了根本原因:

main.cpp(4,23): warning C4427: '/': overflow in constant division, undefined behavior
main.cpp(5,13): warning C4427: '/': overflow in constant division, undefined behavior
main.cpp(4,1): error C2124: divide or mod by zero

你有 UB,MSVC 決定通過溢出到零來處理它。 因為新值為零,所以執行除法,編譯器抱怨被零除。

編碼時,將警告設置為 4 級,並打開將警告視為錯誤。 這樣你就被迫修復你的警告。 很可能第一個警告是之后所有其他問題的原因。 通過被迫修復列表中的第一個警告,您可能會修復大部分或所有其他問題。

C11 的 n1570 草案在 6.5.5 乘法運算符 §6 中說(強調我的):

當整數被除法時, / 運算符的結果是代數商,其中任何小數部分被丟棄。 如果商 a/b 是可表示的,則表達式 (a/b)*b + a%b 應等於 a; 否則, a/b 和 a%b 的行為都是 undefined

我們處於極端情況。 讓我們暫時忘記表示的操作:

-2147483647 - 1 = -2147483648       (1)
-2147483648 / (-1) = 2147483648     (2)

現在我們有了一個 2 補碼的 32 位整數系統。 所以 INT_MAX 是 2147483647 而 INT_MIN 是 -2147483648

所以(1)很好,我們得到可以表示為有符號整數的 INT_MIN。 但是 (2) 給出 INT_MAX + 1 不能。 所以這個操作看起來是有效的,只是它的結果不能用 int 表示。 由於第 6 節,結果是明確未定義的,任何行為在標准觀點上都是合法的。 因此,當 MSVC 決定在實際問題不是這樣的情況下引發除以 0 錯誤時,它是符合標准的。

我經常討厭 Microsoft 錯誤消息不相關,但除了這里 integer 溢出永遠不會引發任何錯誤,結果通過刪除超過 32 的位靜默帶入 [INT_MIN,INT_MAX]。但在這里你會得到 x / (-1 ) == x,而它是除法中唯一可能的溢出。 MSVC 設計者認為這確實是一個需要引發錯誤的特殊情況。 他們搜索了一個除法可能引發的錯誤,只找到了0除法,所以他們使用了它。

他們本可以使用更明確的信息,但由於標准允許任何行為,他們只是選擇了最便宜的方式......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM