[置顶]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的更多相关文章

  1. [置顶]Win2012R2的一个Bug安装群集后可能引发的软件崩溃问题及相应补丁

    [置顶]Win2012R2的一个Bug安装群集后可能引发的软件崩溃问题及相应补丁 如标题,笔者查阅资料发现微软声称安装故障转角色后就可能发生上述描述问题,但不止于SSMS崩溃.建议使用win2012R ...

  2. VC2013的一个bug

    前段时间在尝试使用一个C++的GUI库nana.这个库最大的特点在于使用现代C++风格去编写GUI程序,而不需要使用大量的比较丑陋的代码(如MFC中的各种宏),或者其它的非C++元素.这是一个比较新的 ...

  3. [置顶] Hibernate的一个经典异常

    异常为: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was a ...

  4. [置顶] 请听一个故事------>你真的认为iPhone只是一部手机?苹果惊天秘密!!

    在网上看到的一篇小说,感觉有点意思,转载过来大家一起围观下,作者很幽默很风趣. 导读:iPhone的隐藏功能!Jobs的军方身份!图灵服毒自杀的传奇故事!中兴华为的神秘背景! 你真的认为iPhone只 ...

  5. [置顶] 遇到难题(bug)的解决方法心得

    今天早上花了2个小时解决一个问题...界面抖动.. 最近把淄博项目的界面用BT改了,后来发现4个界面之间切换会抖动.. 就是整个界面会左右抖动... 文章出处: PHP攻城师 www.phpgcs.c ...

  6. [置顶] sscanf() - 从一个字符串中读进与指定格式相符的数据

    在做一道九度上机题时,突然发现sscanf()函数非常有用,就顺便从网上搜集资料整理一下. sscanf() 的作用:从一个字符串中读进与指定格式相符的数据. 原型: int sscanf (cons ...

  7. [置顶] 自己写一个简单通用的Makefile

    转自:http://blog.csdn.net/u011913612/article/details/52102241 一.makefile的作用 Makefile是用于自动编译和链接的,一个工程有很 ...

  8. WPF实现只打开一个窗口,并且重复打开时已经打开的窗口置顶

    内容来自:https://codereview.stackexchange.com/questions/20871/single-instance-wpf-application 第一步:添加Syst ...

  9. win8.1系统下,点击一个窗口,【当前活动窗口】该窗口无法置顶

    两个或多个窗口同时显示在桌面的时候,点击下一层的窗口,无法置顶显示,无论怎么点击,还是隐藏在原置顶窗口的后面,只能手动把原置顶窗口最小化后,才能看到.例如,A窗口现在置顶,B窗口在A的后面,露出来一部 ...

随机推荐

  1. js 实现图片旋转角度

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. eclipse下使用maven配置库托管jar包

    1.项目是通过maven配置库托管jar包 首先要保证maven配置库中有相应的jar包才能通过这个方法来添加jar包.maven的有点就是把要用到的jar包统一放在一个配置库中,在某个项目需要用到这 ...

  3. SCNU省选校赛第二场B题题解

    今晚的校赛又告一段落啦,终于"开斋"了! AC了两题,还算是满意的,英语还是硬伤. 来看题目吧! B. Array time limit per test 2 seconds me ...

  4. STUN/TURN/ICE协议在P2P SIP中的应用(一)

    1           说明 本文详细描述了基于STUN系列协议实现的P2P SIP电话过程,其中涉及到了SIP信令的交互,P2P的原理,以及STUN.TURN.ICE的协议交互 本文所提到的各个服务 ...

  5. wamp配置

    # #localhost # <VirtualHost *:> DocumentRoot "D:/software/wamp/www" ServerName local ...

  6. java中的多线程——进度1

    import java.util.*;public static void main(String[] args) {/*final可以修饰类,方法,变量.final修饰的类不可以被继承.final修 ...

  7. MySQL的基本

    MySQL的基本语法 left JOIN 左表匹配右表 有没有内容全部匹配 SELECT Persons.LastName, Orders.OrderNo FROM Persons INNER JOI ...

  8. javascript 写策略模式,商场收银打折优惠策略

    [Decode error - output not utf-8] ----------------------------- 购物清单 方便面 : 100 x 50 = 5000 | 4000 菊花 ...

  9. HTML5格式化

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  10. javabean+servlet+jsp程序_个人辛苦探索

    主要介绍主流的java web编程技术.设计模式和框架,以及如何利用Eclipese开发Web应用程序. 要点:1.Java Web编程的主要组件技术: 2.MVC设计模式: 3.用Eclipse构建 ...