x64 平台上调试器中的奇怪三元运算符行为
我在 C# 代码中使用了一个非常简单的三元表达式:
helperClass.SomeData = helperClass.HasData ? GetSomeData() : GetSomeOtherData();
在这两种情况下,表达式的每个路径上的函数都返回一个非空对象,但如果我在调试器中查看结果,它会为空,直到我引用它在代码中,例如使用断言:
Debug.Assert(helperClass.SomeData != null);
只有当我在调试模式下使用“x64”或“任何CPU”平台设置时,才会出现这种情况。在“x86”模式下没问题。
在假设我在编译器或调试器中发现错误之前,我会尝试非常谨慎,但我找不到对此行为的任何其他解释。
这是一个完整的类来进行重现,只需在 x64 模式下的调试器中调用 SomeClass.SomeAction() 并逐步查看它:
public class SomeClass {
public bool HasData;
public object SomeData;
private SomeClass() {
HasData = false;
}
public static void SomeAction() {
var helperClass = new SomeClass();
// Exhibits weird debugger behavior of having helperClass.SomeData = null after this line:
helperClass.SomeData = helperClass.HasData ? GetSomeData() : GetSomeOtherData();
// Note that trying helperClass.SomeData.ToString() returns a debugger error saying SomeData is null
// But this code is just fine
//if(helperClass.HasData) {
// helperClass.SomeData = GetSomeData();
//}
//else {
// helperClass.SomeData = GetSomeOtherData();
//}
// In both cases though, after this line things are fine:
Debug.Assert(helperClass.SomeData != null);
}
private static object GetSomeData() {
return new object();
}
private static object GetSomeOtherData() {
return new object();
}
}
我是否遗漏了某些内容,或者这是 x64 调试器中的错误?我正在使用调试模式,因此不应存在任何优化。
I'm using a very simple ternary expression in my C# code:
helperClass.SomeData = helperClass.HasData ? GetSomeData() : GetSomeOtherData();
In both cases, the functions on each path of the expression return a non-null object, but if I look at the result in the debugger, it is null until I reference it in the code such as using an assert:
Debug.Assert(helperClass.SomeData != null);
This only appears to happen if I use an "x64" or "Any CPU" platform setting in Debug mode. It's fine in "x86" mode.
I try to be very cautious before assuming I've found a bug in the compiler or debugger, but I can't find any other explanation for this behavior.
Here's a full class to do a repro, just call SomeClass.SomeAction() in the debugger in x64 mode and step through to see it:
public class SomeClass {
public bool HasData;
public object SomeData;
private SomeClass() {
HasData = false;
}
public static void SomeAction() {
var helperClass = new SomeClass();
// Exhibits weird debugger behavior of having helperClass.SomeData = null after this line:
helperClass.SomeData = helperClass.HasData ? GetSomeData() : GetSomeOtherData();
// Note that trying helperClass.SomeData.ToString() returns a debugger error saying SomeData is null
// But this code is just fine
//if(helperClass.HasData) {
// helperClass.SomeData = GetSomeData();
//}
//else {
// helperClass.SomeData = GetSomeOtherData();
//}
// In both cases though, after this line things are fine:
Debug.Assert(helperClass.SomeData != null);
}
private static object GetSomeData() {
return new object();
}
private static object GetSomeOtherData() {
return new object();
}
}
Am I missing something or is this a bug in the x64 debugger? I'm using debug mode so no optimizations should be present.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据 Eric Lippert 的建议(这可能是一个错误),我已针对此问题提交了官方 Connect 错误:https://connect.microsoft.com/VisualStudio/feedback/details/684202
感谢大家的反馈!
更新:他们回复我说他们已经在下一版本的编译器中修复了这个极端情况。万岁! :)
Taking Eric Lippert's advice that this is probably a bug, I've filed an official Connect bug for this issue: https://connect.microsoft.com/VisualStudio/feedback/details/684202
Thanks everyone for your feedback!
UPDATE: They got back to me and said they've fixed this corner case in the next version of the compiler. Hooray! :)
对我来说,这似乎不是调试器中的错误,但可能是编译器的错误...
当将代码更改为
生成的 IL 时不同,并且调试器按预期工作...
to me this doesn't seem a bug in the debugger but possibly of the compiler...
when changing the code to
the IL generated is different and the debugger works as expected...