Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# x64平台上调试器中奇怪的三元运算符行为_C#_Visual Studio 2010_Ternary Operator - Fatal编程技术网

C# x64平台上调试器中奇怪的三元运算符行为

C# x64平台上调试器中奇怪的三元运算符行为,c#,visual-studio-2010,ternary-operator,C#,Visual Studio 2010,Ternary Operator,我在C代码中使用了一个非常简单的三元表达式: 在这两种情况下,表达式的每个路径上的函数都返回一个非null对象,但如果我在调试器中查看结果,它将为null,直到我在代码中引用它,例如使用断言: Debug.Assert(helperClass.SomeData != null); 只有在调试模式下使用“x64”或“任意CPU”平台设置时,才会出现这种情况。在“x86”模式下可以 在假设我在编译器或调试器中发现了错误之前,我会非常谨慎,但我找不到任何其他解释来解释这种行为 这里有一个完整的类来执

我在C代码中使用了一个非常简单的三元表达式:

在这两种情况下,表达式的每个路径上的函数都返回一个非null对象,但如果我在调试器中查看结果,它将为null,直到我在代码中引用它,例如使用断言:

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调试器中的一个错误?我正在使用调试模式,因此不应存在任何优化。

对我来说,这似乎不是调试器中的错误,但可能是编译器的错误

将代码更改为

{ helperClass.SomeData = helperClass.HasData ? GetSomeData() : GetSomeOtherData(); }

生成的IL不同,调试器按预期工作…

根据Eric Lippert的建议,这可能是一个bug,我已经针对这个问题提交了一个官方Connect bug:

谢谢大家的反馈


更新:他们回复我说他们已经在下一版本的编译器中修复了这个死角。万岁!:)

请注意,生成的调试符号和生成的优化实际上是正交的。同时启用调试符号和优化是合法的,尽管有些不寻常。可能需要再次检查您是否处于这种奇怪的配置中。对于我的活动(调试/x64)配置,“生成”选项卡下的“优化代码”复选框未选中。我应该去别的地方看看吗;听起来这不是问题所在。只需尝试一下(关闭优化代码,打开调试),就可以看到所描述的行为-在x86中,直接在SomeData一行之后null,而在x64中,第一次访问时它“变为!=null”(不是从调试器而是在代码中)。。。比较一下生成的IL看起来会很有趣…@杰夫:听起来确实像是一个bug,但我没有复制它,所以我无法确认。听起来很适合在Connect上发布。我不知道是否已经有案例了。我注意到,多年来出现了一些奇怪的bug,涉及到条件运算符的代码生成和调试;静态确定已知堆栈槽类型的精确CLR规则可能有点棘手,这会导致错误。如果这是另一个,我也不会感到惊讶,但就像我说的,我个人并没有责备它。你为什么要把{}放在它周围呢?我不是说你必须。。。当Reflector在反汇编这行代码时给了我一些奇怪的代码,这似乎是一个bug(也许正如你所建议的,只是在编译器中)。我通过将其转换为if语句来解决它,即使ReSharper认为我这样做是个白痴:)不管ReSharper在这种情况下说什么。。。除了ReSharper有一些绝妙的想法来解决它:-)
{ helperClass.SomeData = helperClass.HasData ? GetSomeData() : GetSomeOtherData(); }