C++ (已知)VC12中的编译器错误?
当使用VC12(在Visual Studio 2013 RTM中)[1]编译此程序时,会导致崩溃(在所有构建配置中),而实际上它不应该: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(); } 我知道有两个无声的坏代码错误可能
#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
[...]