“这充分证明了C++代码和VC++代码是不同的。”这事发生在我引用一个老开源项目的时候,那个作者还在用win7和使用vs2013,出问题的代码,我大致模拟了一下,就是如下这样

内容比较简单,就是一个函数返回一个结构体,我们将它返回值的引用传给另一个函数来输出。我的环境是win10和vs2019,原来作者当然是没有报错的,而我这里报了“取地址操作必需作用于左值”。所谓“左值”指的是可以寻址的值,如果认为返回的值是一个结构体,那它确实应该是一个左值,因为它们之间传递的是引用。如果我稍微加一个缓存变量,如下

则一切运行正常。当时我一直被这个左值纠结,也秉着面向浏览器编程的理念,围绕这方面找了许多例子,错误代码搜索,相似代码查询,却怎么也找不到原因,我甚至怀疑返回结构体这个操作是否有问题,但最终还是无果。后来,我怀疑是不是vs的编译器取地址面向的是函数而不是函数的返回值,所以我决定用GUN套件来编译一下,结果

果然GUN套件才是真正的神啊,它旳意思是临时变量不能取地址,所谓临时变量指的是它值的作用范围只有当前这一行,而函数的返回值就是典型的临时变量,嗯,其实这和编译器的优化有关,从汇编角度来看的话就是值是放在寄存器里的,没有放在内存里,所以不能取地址。简单来说临时变量是右值,当然右值还包括其它的,如立即数等。
其实,遇到这个还是挺开心的,这些东西在有些善于写代码的人手里基本不会出现,一般我们写函数返回值只有两种情况,传值的直接写,传引用的时候要特别地写成指针,比如好的习惯应当这样写

看,这不就正常运行了嘛,不过也有人指出可能是vs2013版本太老,还在使用较老的C标准的原因,比如C++11,而我的电脑最低只有C++14标准。不过追根究底的话,还是因为我太久没有遇到这些错误,搞得这些细节基本都忘记了。不过,最后我是想吐槽一下,这vs好像不是很好用,特别是报错能力,比如我用模板写代码的时候,用vs也太难找错误了吧。哦,还有那个资源管理实在太垃圾了吧。
总之,就这样吧,我并不打算开个新系列,只是有些想抱怨的东西,就随便记录一下吧,这些就整合成编程手记吧。