Visual Studio 2010与Visual Studio 2013——不同的编译器错误——为什么?

4
我们注意到了一些奇怪的东西,无法解释。在一个类中,我们有这两个函数:

def function1(list=[]): list.append(1) return list

def function2(list=[]): list += [1] return list

   Public Overloads Shared Function ToList(ByVal input As Object, _
                                    Optional ByVal StringSeparator As String = ";", _
                                    Optional ByVal CharacterCasing As String = "", _
                                    Optional ByVal StartRow As Integer = 0, _
                                    Optional ByVal EndRow As Integer = -1) As String
            ...
   End Sub

   Public Overloads Shared Function ToList(ByVal Input As Object, _
                            Optional ByVal SplitStringSeparator As String = ",", _
                            Optional ByVal JoinStringSeparator As String = ",", _
                            Optional ByVal PreFixStr As String = "", _
                            Optional ByVal PostFixStr As String = "") As String
           ...
  End Sub

如果我们尝试在VS2013中编译此项目,不会出现任何错误。如果我们尝试在VS 2010中编译完全相同的项目,则会出现以下错误(这是有道理的):
“Public Shared Overloads Function ToList(input As Object,[StringSeparator As String = ";"],[CharacterCasing As String = ""],[StartRow As Integer = 0],[EndRow As Integer = -1]) As String” 和“Public Shared Overloads Function ToList(Input As Object,[SplitStringSeparator As String = ","],[JoinStringSeparator As String= ","],[PreFixStr As String = ""],[PostFixStr As String = ""]) As String”不能重载彼此,因为它们只由可选参数的默认值的差异而不同。
“Public Shared Overloads Function ToList(input As Object,[StringSeparator As String = ";"],[CharacterCasing As String = ""],[StartRow As Integer = 0],[EndRow As Integer = -1]) As String” 和“Public Shared Overloads Function ToList(Input As Object,[SplitStringSeparator As String = ","],[JoinStringSeparator As String= ","],[PreFixStr As String = ""],[PostFixStr As String = ""]) As String”不能重载彼此,因为它们只由可选参数的类型差异而不同。
有人能解释一下,在不同版本的VS中打开相同解决方案包含相同项目时,为什么会有差异,有时会出现错误,有时不会吗?

2
@lll - Roslyn还没有发布,所以不行... - Erik Funkenbusch
1
在VS2013中,如果调用不明确,则会在调用者中出现错误。例如,尝试调用ToList(blah),您将看到以下内容:“由于这些参数,重载分辨率失败,因为没有可访问的'ToList'最具体。”显然,只要确保每个特定的调用都是明确的,他们希望允许这种情况。但是,这仍然无法解释为什么此行为在VS2010和VS2013之间可能会有所不同... - mellamokb
1
@mellamokb 我也刚测试了一下,确认了这个问题。有趣的是,它似乎违反了规范,“重载类型成员必须具有唯一的签名。”和“方法的签名不包括返回类型或参数修饰符,如Optional、ByRef或ParamArray。” - Blorgbeard
1
如果我在VS2010解决方案中手动从命令行调用MSBuild,则可以成功构建。因此,这似乎是仅存在于VS2010 IDE中的规则,在VS2013中已被删除。编辑:实际上,这只适用于安装了VS2010和VS2013的计算机。在仅安装了VS2010的计算机上,MSBuild会生成相同的两个错误。因此,看来安装VS2013包括一个更新的编译器,其与VS2010 IDE的行为不同! - mellamokb
1
@lll - 这意味着他们在自己的开发中使用了Roslyn,而不是说Roslyn在VS2013中.. Roslyn尚未发布,它根本不在2013年的版本中。 - Erik Funkenbusch
显示剩余5条评论
1个回答

6

通过参考源代码查看编译器源代码,我认为我看到它接受第二个函数作为有效的重载,因为默认值具有不同的类型。您可以自己查看vb\language\compiler\symbols\symboltable.cpp,BCSYM::CompareParams()函数。

    // make sure the types being used for the default are the same
    if ( ParmTypeCompareFlags & ( EQ_Shape | EQ_GenericTypeParams ))
    {
        ComparisonFlags |= EQ_OptionalTypes;

        // don't percolate the difference in the type shape on in this case - the difference we care about it is EQ_OptionalTypes
        ParmTypeCompareFlags &= ~(EQ_Shape | EQ_GenericTypeParams);   // <== Here
    }

关闭EQ_Shape是一个错误,这表明参数不同。我无法将其与在VS2010中执行的方式进行比较,因为该版本不可用。
当然,这没有意义。它违反了语言规范的第4.1.1章,该章说:
“具有可选参数的方法被认为具有多个签名,每个签名对应调用者可以传入的参数集。例如,以下方法具有三个对应的签名:”
Sub F(x As Short, _ Optional y As Integer = 10, _ Optional z As Long = 20)
这些是该方法的签名: - F(Short) - F(Short, Integer) - F(Short, Integer, Long)
所以我认为你发现了一个错误。这是一个轻微的错误,无论如何在调用站点解决,你会得到错误BC30521,“重载分辨率失败”。你可以在connect.microsoft.com上报告它。

感谢您的研究,如果您愿意,可以向connect.microsoft.com报告此问题,因为Hans值得因发现这个问题而受到赞扬。我们只是注意到了一种奇怪的行为... - Denis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接