- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我认为这看起来像是 C# 编译器中的错误。
考虑这段代码(在一个方法中):
const long dividend = long.MinValue;
const long divisor = -1L;
Console.WriteLine(dividend % divisor);
它编译时没有错误(或警告)。 似乎是一个错误。运行时,在控制台上打印 0
。
然后在没有 const
的情况下,代码:
long dividend = long.MinValue;
long divisor = -1L;
Console.WriteLine(dividend % divisor);
运行时,它会正确地导致抛出 OverflowException
。
C# Language Specification 专门提到了这种情况,并说将抛出 System.OverflowException
。它似乎不依赖于 checked
或 unchecked
的上下文(此外,余数运算符的编译时常量操作数的错误与 checked
和 未选中
)。
同样的错误发生在 int
(System.Int32
),而不仅仅是 long
(System.Int64
) .
相比之下,编译器使用 const
操作数处理 dividend/divisor
比 dividend % divisor
好得多。
我的问题:
我说得对吗,这是一个错误?如果是,是否是他们不想修复的众所周知的错误(因为向后兼容,即使将 % -1
与编译时常量 一起使用是相当愚蠢的-1
)?还是我们应该报告它,以便他们可以在即将推出的 C# 编译器版本中修复它?
最佳答案
这种极端情况在编译器中得到了非常明确的解决。 Roslyn source 中最相关的注释和代码:
// Although remainder and division always overflow at runtime with arguments int.MinValue/long.MinValue and -1
// (regardless of checked context) the constant folding behavior is different.
// Remainder never overflows at compile time while division does.
newValue = FoldNeverOverflowBinaryOperators(kind, valueLeft, valueRight);
和:
// MinValue % -1 always overflows at runtime but never at compile time
case BinaryOperatorKind.IntRemainder:
return (valueRight.Int32Value != -1) ? valueLeft.Int32Value % valueRight.Int32Value : 0;
case BinaryOperatorKind.LongRemainder:
return (valueRight.Int64Value != -1) ? valueLeft.Int64Value % valueRight.Int64Value : 0;
还有旧版 C++ 编译器的行为,一直追溯到版本 1。来自 SSCLI v1.0 分发版,clr/src/csharp/sccomp/fncbind.cpp 源文件:
case EK_MOD:
// if we don't check this, then 0x80000000 % -1 will cause an exception...
if (d2 == -1) {
result = 0;
} else {
result = d1 % d2;
}
break;
因此得出的结论是,这并没有被忽视或遗忘,至少对于从事编译器工作的程序员来说,它可能被认为是 C# 语言规范中不够精确的语言。在 this post 中了解更多关于这个 killer poke 引起的运行时问题的信息.
关于c# - 为什么编译器评估余数 MinValue % -1 与运行时不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18299044/
我想知道,为什么 SqlDateTime.MinValue 与 DateTime.MinValue 不一样? 最佳答案 我认为 SQL 和 .NET 的 Date 数据类型之间的差异源于 SQL Se
在 C# 中我看到了 -1 * int.MinValue == int.MinValue 这是一个错误吗?当我试图实现搜索树时,它真的把我搞砸了。我最终使用了 (int.MinValue + 1) 这
我第一次尝试这个(在 vb.net 中) (Double.MinValue + Double.Epsilon) > Double.MinValue 但这评估为假。然后我尝试了这个 (Double.Mi
考虑下面的 C# 代码: public class Program { public static void Main(string[] args) { //Your
是否可以为 minValue 规则编写依赖回调,例如使用所需的文本? 我有 2 个必填字段 -> 已付价格和已见价格(对于回扣表格)。我尝试写这样的东西: minValue: functio
我正在使用返回 1.1.0001 的 Datetime.Minvalue。此值无法存储到 DB,因为年份小于 1975。 是否可以将 DateTime.Minvalue 覆盖为 1.1.1901? 问
我正在尝试将 Int64.MinValue (-0x8000000000000000) 写为负十六进制数,但 Visual Studio 2010 不允许我这样做,因为它假定 0x8000000000
最近在分析 session 期间,一种方法引起了我的注意,在分析器的反编译版本中它看起来像这样: public static double dec2f(Decimal value) { if
我刚刚发现我的 SqlDateTime.MinValue 在不同的机器上是不同的。 有时是 = DateTime(1953, 1, 1, 0, 0, 0); 但在其他机器上它是 = DateTime(
我正在学习 Java 并正在阅读一本 Java 编程书。我已经到了他们教我有关数组的程度。 因此,我创建了一个采用非特定数量的命令行参数的数组,并将其与书籍代码结合起来以打印出该数组中的最大值。它工作
我正在编写一个使用 Quartz.Net 的 F# 服务轮询另一个服务(已用 C# 编写): [] [] type PollingJob() = interface IJob with
所以我目前正在尝试测试一个使用随机函数的函数。为了测试它,我将一个种子值传递给 C# Random 函数。 (即系统。随机) 我的测试用例涉及使用 int.MaxValue 和 int.MinValu
我们试图在我们的应用程序中覆盖 DateTime.MinValue,但是这样做我们注意到我们的 Web 服务超时,下面是示例代码。不确定哪里出了问题/我们缺少什么。 public MainWindo
如演示中所示,maxValue 设置为 2017 年,但图表一直到 2020 年。 如何让图表真正停在 2017 年?它在我的页面上占用了太多空间,因此我想对其进行优化 See demo fiddle
我在使用 TimeSpans 时找到了关于 TimeSpan.MinValue 的信息在 MSDN 中。我想知道为什么他们将其直接包含在类里面,或者更好:是否有一个经典示例说明您为什么/何时要使用它。
当我写这段代码的时候 Console.WriteLine(-1 * int.MinValue); 或 int a = -1 * -2147483648; 我得到一个错误 The operation o
我找不到如何检查大于 0 的值,因为 minValue(0) 也接受 0,但是如果使用 minValue(1) 那么任何介于 0 之间的小数并且 1 也不会被接受。 我也不知道为什么我不能使用来自 d
我正在尝试绘制具有对数刻度的 Google 条形图。但是,它从 1 开始,而不是 0。这看起来像是错误数据,因为具有一个值的条目在呈现时没有条形。我尝试将 minValue 设置为零,但当 logSc
我认为这看起来像是 C# 编译器中的错误。 考虑这段代码(在一个方法中): const long dividend = long.MinValue; const long divisor = -1L;
我似乎无法将 sqldatatime.minvalue 转换为 datetime 对象。 我试过: Datetime dt = Convert.ToDateTime(SqlDateTime.MinVa
我是一名优秀的程序员,十分优秀!