C++ (已知)VC12中的编译器错误?

C++ (已知)VC12中的编译器错误?,c++,visual-c++,visual-studio-2013,compiler-bug,C++,Visual C++,Visual Studio 2013,Compiler Bug,当使用VC12(在Visual Studio 2013 RTM中)[1]编译此程序时,会导致崩溃(在所有构建配置中),而实际上它不应该: #include <string> void foo(std::string const& oops = {}) { } int main() { foo(); } #包括 voidfoo(std::stringconst&oops={}) { } int main() { foo(); } 我知道有两个无声的坏代码错误可能

当使用VC12(在Visual Studio 2013 RTM中)[1]编译此程序时,会导致崩溃(在所有构建配置中),而实际上它不应该:

#include <string>

void foo(std::string const& oops = {})
{
}

int main()
{
    foo();
}
#包括
voidfoo(std::stringconst&oops={})
{
}
int main()
{
foo();
}
我知道有两个无声的坏代码错误可能与之相关:

老实说,我认为这些是不同的,虽然。有人知道吗

  • 此连接上是否存在活动跟踪的错误
  • 是否有解决方法(或明确描述导致此错误的情况,以便我们可以在代码库中查找/避免它)


  • (1)只需使用C++控制台应用程序向导创建一个空项目。为简单起见,请禁用预编译标题并保留所有默认值:

    已将活动问题发回。发布的示例代码为:

    Compile and run following code in VS2013
    
    #include <string>
    
    void f(std::string s = {}) {
    }
    
    int main(int argc, char* argv[]) {
        f();
        return 0;
    }
    
    或者只是老式的(如果您不介意引入重载):


    当默认参数是初始值设定项列表时,
    visualstudio
    似乎就其调用的构造函数而言被破坏了。此代码:

    #include <iostream>
    
    struct test {
      test ()  { std::cout << "test ()" << std::endl ; } 
      test (int)  { std::cout << "test (int)" << std::endl ; }
    };
    
    void func( test const &s = {} )
    {
    }
    
    int main()
    {
        test s = {} ;
        func() ;
    }
    
    Visual Studio
    会生成以下结果:

    test ()
    test (int)
    
    对于此代码:

    #include <iostream>
    #include <initializer_list>
    
    struct test {
      test ()  { std::cout << "test ()" << std::endl ; };
    
      test (int)  { std::cout << "test (int)" << std::endl ; };
      test ( std::initializer_list<int>) { std::cout << "test (initializer_list<int>)" << std::endl ; } ;
    };
    
    void func( test const &s = {0} )
    {
    }
    
    int main()
    {
        test s = {0} ;
        func() ;
    }
    
    Visual Studio
    产生此错误时:

     error C2440: 'default argument' : cannot convert from 'initializer-list' to 'const test &'
        Reason: cannot convert from 'initializer-list' to 'const test'
        No constructor could take the source type, or constructor overload resolution was ambiguous
    
    更新

    为了进行合理性检查,我回到了标准,以确保在这种差异的根源上没有一些奇怪的规则,或者可能有一些限制导致代码格式错误。据我所知,这段代码不是格式错误。第
    8.3.5节
    语法特别允许:

    parameter-declaration:
      attribute-specifier-seqopt decl-specifier-seq declarator
      attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
      [...]
    

    它似乎不像第
    8.5节的初始值设定项或
    8.3.6节的默认参数添加了任何限制,但此缺陷报告和工作文件明确了其目的,并概述了对标准所做的更改,以允许它,并且查看增量没有明显的限制。

    返回0缺失,但似乎不相关…@Mario,不需要。也没有关系。@Sehe怎么办?我不知道这是相关的还是相关的。@remyabel谢谢!这正是我想要的。如果您不介意发布作为答案(如果您愿意,我可以添加一些变通方法),我们可以将此作为答案。看起来这在一般情况下是个问题,而我添加了明显的变通方法。这在某种程度上回答了要寻找什么的问题。我想搜索
    ={}
    {{}
    ,{}
    在某种程度上可以找到这种情况。不过,我并不完全确信这会找到(所有)相关的呼叫站点。我也会在上对此进行评论,以防万一他们需要任何帮助:/(好吧,也许他们需要帮助,认识到这个bug具有破坏性)@错误报告中添加了sehe注释
    #include <iostream>
    #include <initializer_list>
    
    struct test {
      test ()  { std::cout << "test ()" << std::endl ; };
    
      test (int)  { std::cout << "test (int)" << std::endl ; };
      test ( std::initializer_list<int>) { std::cout << "test (initializer_list<int>)" << std::endl ; } ;
    };
    
    void func( test const &s = {0} )
    {
    }
    
    int main()
    {
        test s = {0} ;
        func() ;
    }
    
     test (initializer_list<int>)
     test (initializer_list<int>)
    
     error C2440: 'default argument' : cannot convert from 'initializer-list' to 'const test &'
        Reason: cannot convert from 'initializer-list' to 'const test'
        No constructor could take the source type, or constructor overload resolution was ambiguous
    
    parameter-declaration:
      attribute-specifier-seqopt decl-specifier-seq declarator
      attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
      [...]