[置顶]VC2013的一个bug
前段时间在尝试使用一个C++的GUI库nana。这个库最大的特点在于使用现代C++风格去编写GUI程序,而不需要使用大量的比较丑陋的代码(如MFC中的各种宏),或者其它的非C++元素。这是一个比较新的库,作者是个中国人,有兴趣的朋友可以去试一试,由于使用大量的C++11特性,所以需要VC2013或者GCC4.7以上的编译器。使用过程中无意间发现了VC2013的一个重载决议(overload resolution)上的一个bug,这边贴出来跟大家分享一下,或许可以帮助大家少走点弯路。
我写了以下简单的代码来重现这个问题:
#include <iostream>
#include <string> class foo{
public:
void bar(std::string = {});
}; void foo::bar(std::string str)
{
std::cout << str << std::endl;
} int main()
{
foo f;
f.bar();
}
编译运行这段代码,弹出一个错误:

按照错误提示,可以找到对应的代码1168行:

也就是这一行:
_DEBUG_POINTER(_Ptr);
加个断点可以发现这里面_Ptr为空指针,所以导致程序crash。这个问题其实比较容易理解,写一个更简单的例子就可以发现问题:
#include <string> int main()
{
std::string str = nullptr;
}
这段代码通过nullptr去初始化一个string,而这显然是错误的。
但问题在于,在最初的那段代码中,
void bar(std::string = {});
这个函数声明明明是给了函数bar一个默认参数,使其构造出一个空字符串。但为什么会调用xstring中的1168行呢?也就是参数为一个指针的assign函数呢?
经过多次试验以后发现,VC将上面这个声明理解为了:
void bar(std::string = {nullptr});
也就是用一个空指针去初始化一个string,从而导致了问题。同样的代码,在GCC4.8中是没有任何问题的。并且如果把
void bar(std::string = {});
改为:
void bar(std::string = std::string());
在VC2013里也没有问题了。这也就说明了VC2013在处理{}来初始化对象时的确存在重载决议的问题。
之所以之前说这个问题比较隐蔽,是因为这种情况只出现在类的成员函数中,如果是普通函数,就没有这个问题:
#include <iostream>
#include <string> void func(std::string = {}); int main()
{
func();
} void func(std::string str)
{
std::cout << str << std::endl;
}
上面这段代码和刚开始那段代码几乎一样,唯一的不同在于func是一个普通函数,而bar是一个成员函数。
不知道大家有没有遇到类似的问题?
[置顶]VC2013的一个bug的更多相关文章
- [置顶]Win2012R2的一个Bug安装群集后可能引发的软件崩溃问题及相应补丁
[置顶]Win2012R2的一个Bug安装群集后可能引发的软件崩溃问题及相应补丁 如标题,笔者查阅资料发现微软声称安装故障转角色后就可能发生上述描述问题,但不止于SSMS崩溃.建议使用win2012R ...
- VC2013的一个bug
前段时间在尝试使用一个C++的GUI库nana.这个库最大的特点在于使用现代C++风格去编写GUI程序,而不需要使用大量的比较丑陋的代码(如MFC中的各种宏),或者其它的非C++元素.这是一个比较新的 ...
- [置顶] Hibernate的一个经典异常
异常为: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was a ...
- [置顶] 请听一个故事------>你真的认为iPhone只是一部手机?苹果惊天秘密!!
在网上看到的一篇小说,感觉有点意思,转载过来大家一起围观下,作者很幽默很风趣. 导读:iPhone的隐藏功能!Jobs的军方身份!图灵服毒自杀的传奇故事!中兴华为的神秘背景! 你真的认为iPhone只 ...
- [置顶] 遇到难题(bug)的解决方法心得
今天早上花了2个小时解决一个问题...界面抖动.. 最近把淄博项目的界面用BT改了,后来发现4个界面之间切换会抖动.. 就是整个界面会左右抖动... 文章出处: PHP攻城师 www.phpgcs.c ...
- [置顶]
sscanf() - 从一个字符串中读进与指定格式相符的数据
在做一道九度上机题时,突然发现sscanf()函数非常有用,就顺便从网上搜集资料整理一下. sscanf() 的作用:从一个字符串中读进与指定格式相符的数据. 原型: int sscanf (cons ...
- [置顶]
自己写一个简单通用的Makefile
转自:http://blog.csdn.net/u011913612/article/details/52102241 一.makefile的作用 Makefile是用于自动编译和链接的,一个工程有很 ...
- WPF实现只打开一个窗口,并且重复打开时已经打开的窗口置顶
内容来自:https://codereview.stackexchange.com/questions/20871/single-instance-wpf-application 第一步:添加Syst ...
- win8.1系统下,点击一个窗口,【当前活动窗口】该窗口无法置顶
两个或多个窗口同时显示在桌面的时候,点击下一层的窗口,无法置顶显示,无论怎么点击,还是隐藏在原置顶窗口的后面,只能手动把原置顶窗口最小化后,才能看到.例如,A窗口现在置顶,B窗口在A的后面,露出来一部 ...
随机推荐
- java之sleep、wait、yield、join、notify乱解
① 这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类. sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用b的sleep方法,实际上还是 ...
- 菜鸟的MySQL学习笔记(三)
4-1插入记录INSERT INSERT [INTO] tbl_name [(col_name)] {VALUES|VALUE} ({expr|DEFAULT},...), (...), ... ...
- DOM 文档对象模型
document 对象(作为对象),是 DOM 的核心作用:对内容,属性,样式等操作属性:title:设置/返回当前文档的标题url:返回当前文档的 urlinnerHTML:获取指定对象内的内容bg ...
- Invoke()方法的使用
在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法,Invoke 和 BeginInvoke 就是为了解决这个问题而出现的,使你在多线程中安全的更新界 ...
- 用javascript操作xml(三)关于Jquery的html()不兼容IE的解决办法
当 $("#xxx").html(data); 不兼容,方法替换为 document.getElementById("xxx").innerHTML=data;
- 怎样清除td和input之间空隙
<style> input {background:red;border:none;height:30px;margin:0px} td {background-color:blue;pa ...
- ssh登录docker容器
ssh登录docker容器1.启动一个docker容器# docker run -t -i ubuntu/ruby:v1 /bin/bash2.然后在容器里,安装openssh-server open ...
- sql server 表空间
在SqlServer2005中,建表时是默认把所有的表都保存在PRIMARY默认表空间中的.当数据库中表很多,并且数据量很大时,会导致数据库性能严重下降,有必要将一些大的表放到不同的表空间中去.主要的 ...
- 工作总结:文件对话框的分类(C++)
原文地址:http://www.jizhuomi.com/software/173.html 文件对话框分为打开文件对话框和保存文件对话框,相信大家在Windows系统中经常见到这两种文件对话框.例如 ...
- hdu 1875
题目很简单,我却WA了几十次,找错误找了我一个小时: 蛋都碎了! 后来发现错误的地方竟然是memset: 用一个循环来替代它就A了:╮(╯▽╰)╭ 今晚回去好好的看看memset!!! 发个代码纪念下 ...