c++ - 这个 Visual Studio 编译器错误 'divide or mod by zero' 是一个错误吗?

标签 c++ visual-studio

我在 Visual Studio 2019 上,当我尝试编译它时:

#include <iostream>

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

在这两种情况下我都遇到编译器错误:

C2124 'divide or mod by zero'

据我所知,没有被零除或模数。

最佳答案

C11 的 n1570 草案在 6.5.5 乘法运算符§6 中说(强调我的):

When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded. If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a; otherwise, the behavior of both a/b and a%b is undefined.

我们处于极端情况。让我们暂时忘记表示的操作:

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

现在我们有一个包含 2 补码的 32 位整数的系统。所以INT_MAX是2147483647,INT_MIN是-2147483648

所以 (1) 很好,我们得到 INT_MIN 可以表示为带符号的 int。但是 (2) 给出了 INT_MAX + 1 而不能。所以这个操作看起来是有效的,只是它的结果不能用 int 表示。由于 §6,结果是明确未定义的,从标准的角度来看,任何行为都是合法的。因此,当 MSVC 决定引发除数为 0 的错误时,实际问题并非如此,这是符合标准的。

我经常讨厌 Microsoft 错误消息,因为它不相关,但除了这里整数溢出不会引发任何错误,结果会通过丢弃超过 32 位的位静默地进入 [INT_MIN,INT_MAX]。但在这里你会得到 x/(-1) == x,而它是除法中唯一可能的溢出。 MSVC 设计者认为这确实是需要引发错误的特殊情况。他们搜索了一个除法可能引发的错误,只找到除以 0 的除法,所以他们使用了它。

他们本可以使用更明确的消息,但由于标准允许任何行为,他们只是选择了最便宜的方式...

关于c++ - 这个 Visual Studio 编译器错误 'divide or mod by zero' 是一个错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66550005/

相关文章:

c++ - 隐藏结构细节的迭代器适配器

.net - 使用 VB.NET 更新 MySQL

c# - 链接的 .CS 文件和 WCF 服务的引用不明确

c# - Microsoft Visual Studio C# 安装程序

c++ - WinDBG 适用于从 Visual Studio 2015 保存的转储,但不适用于任务管理器。显示异常代码 "not found"

c# - 如何从 C# 项目的构建事件访问 Visual Studio 解决方案级平台?

c# - 在 C# 中从 C++ 实现函数(MAKE_HRESULT - Windows 函数)

c++ - Windows 应用商店应用程序的扩展 SDK 在远程调试期间不起作用

c++ - malloc 触发断点

c++ - 即使缺少函数定义,编译也会成功