令人困惑的return by value

__report_gsfailure中UEF的特殊行为 <br />原本以为对UEF的逻辑已经大概了解了(理解UnhandledExceptionFilter),最近调试__report_gsfailure的时候却碰到了新问题。从VS2005以来,编译器添加了对栈的保护检查以防止buffer overrun的危害。一旦发现栈的内容出现错误,会调用__report_gsfailure,代码如下:­<br />1. DebuggerWasPresent = IsDebuggerPresent(); ­ <br />2. _CRT_DEBUGGER_HOOK(_CR 阅读详情

 

问题从这里开始。
class X;
const X operator+( const X& x1, const X& x2 );
X foo()
{
return X(a+b);
}
和
X foo()
{
X xx(a+b);
return xx;
}
这两个函数,有什么区别?
这个问题牵涉到C++的内部处理,下面是其更通用的模式。
X foo()
{
X xx;
// process
...
return xx;
}
C++如何处理return by value,传统的方法是修改函数原型。
void foo( X& r )
{
X xx;
xx.X(); //ctor
// process
...
r.XX( xx ) // copy ctor
}
这样就把xx的值给返回了,这里有一个xx的临时对象的ctor和dtor。
于是乎。
X obj = foo();
被转化为 
X obj;
foo( obj );
但是,对于程序员来说,是可以进行一些优化的,其方法就是采用ctor返回,
X foo()
{
return X( ... );
}

编译器处理过后,为这样。
void foo( X &r )
{
return r.X(...);
}
看出来了吗?这里少个对象(即上面的xx)的ctor和dtor,效率自然提高。
更进一步,如果这个函数是inline的,则
X obj = foo();
被处理成
X obj;
obj.X(...);
Bingo!!
真的是棒呆了,C++注重的效率得以完全体现。
这种优化我称之为ARV( anonymous return value )优化,:)
然而对于前者NRV( named return value ),我们又该如何呢?
答案是:没有办法,唯一可作的是期待编译器给我们一些帮助。
如果我们的编译器够power的话,那么
X foo()
{
X xx;
// process
...
return xx;
}
可能被处理成:
void foo( X &r )
{
// ctor
r.X();
// process
...
}
在这里,同样没有出现named object(指xx)的ctor和dtor,但是作为一个应该把握全局的程序员,我劝你不要太指望它。
首先,它还是调用了default ctor,这在ARV中是不存在的。
其次,你无法知道编译器是否正在这样做,毕竟对于厂家来说,它有这样的权利不让你知道细节。
再次,编译器就算有这样的能力,但仅仅对一些简单的函数有效,而对于实际编程来说,函数往往很复杂,
比如具有多个分支返回的函数,编译器就只能叹气了。
还有,在函数开头就声明对象的作法,可不是正宗C++的style,C++一向提倡“只有在必要是才使用”,真正的C++程序员应该牢记这一点。
最后,从C++编译器历史来看,在优化过程中,匿名对象比命名对象更容易消除,你要充分利用它。
答案:
对于这么一个简单的函数,如果你的编译器支持NRV优化,则结果是一样的,否则。。。
而ARV优化总是支持的。
那采用ARV这样做有没有缺点呢?
或许吧,毕竟你要写一堆ctor用于特殊用途了。:)
注:
本文中的例子选自<<Inside C++ Object Model>>,要感谢Lippman给C++程序员们写了这么一本好书,同样感谢JJhou给中国程序员的翻译。
本文还参考了MEC(More Effective C++)

SAP SearchHelp避坑指南:F4IF_INT_TABLE_VALUE_REQUEST的5个常见错误及解决方法 本文详细解析了SAP开发中使用F4IF_INT_TABLE_VALUE_REQUEST函数实现SearchHelp功能时的5个常见错误及解决方案,包括字段大小写问题、回调函数配置错误、值表处理不当、动态字段绑定问题和多值返回处理。通过实战案例和代码示例,帮助开发者高效避坑,提升F4帮助功能的稳定性和用户体验。 阅读详情

相关推荐

C++20协程promise_type核心方法调用时机与实现原理详解

协程是现代编程中实现异步操作和生成器的重要技术,它通过挂起和恢复执行流程来优化资源利用和简化并发编程。在C++20协程框架中,promise_type作为编译器与用户代码之间的关键契约,定义了协程的生命周期控制逻辑。其核心方法如get_return_object、initial_suspend、return_value和final_suspend的调用时机与返回值,直接决定了协程的状态转换、内存管理及异常处理行为。深入理解这些方法的协作机制,对于实现高性能、无内存泄漏的自定义协程类型(如Task<T>或Ge

weixin_33937778的博客 291

深入C/C++之基于Cookie的安全检查(VS2005)(转)

昨天在试着逆向一个有时间期限的LIB时,发现一些特别的检查函数,在之前的VC2003中是没有的,这些函数可谓是重量级函数。由于个人比较看不惯自己不懂的东西,出于不愤之情绪研究了下这些函数。首先在这里介绍个人认为较之其他几个更为重要的一种安全检查方式——基于Cookie的缓冲区溢出安全检查! 为了在发布版本中也能检测到缓冲区溢出,防止程序因缓冲区而受到攻击,VS2005(VC8)便增加

ldh_cq的专栏 764

KingbaseES PL/SQL参数模式深度解析:IN、OUT、IN OUT实战与性能优化

在数据库编程中,存储过程和函数的参数传递机制是核心基础概念,它决定了数据在调用者与子程序之间的流向与处理方式。其原理主要涉及值传递与引用传递两种底层机制,直接影响内存使用和程序性能。掌握参数模式的技术价值在于能够编写出更安全、高效且易于维护的数据层代码,尤其在处理大数据量、高并发场景时,合理选择参数模式能显著减少不必要的内存拷贝与锁竞争。应用场景广泛,包括但不限于数据查询封装、事务处理、批量操作以及模块化业务逻辑设计。本文聚焦于人大金仓KingbaseES数据库,深入探讨其PL/SQL兼容性中的IN、OUT

weixin_34342905的博客 88

VC内存溢出一例 –- 调用约定不一致 (0)

最近在写一个程序,调用了多个DLL,每个DLL代码都支持多线程,Debug的模式下基本调通了,但是在Release模式下,程序因为内存溢出而崩溃,中断在gs_report.c文件的298行位置(_CRT_DEBUGGER_HOOK(_CRT_DEBUGGER_GSFAILURE),如下图:            由于问题是出自某个DLL模块中,并且是多线程的,并且出现中断的断点无法回溯,很

Never too late to study 2426

Grafana企业版vs开源版:从安装到插件管理的完整对比实测(含离线部署技巧)

本文深入对比Grafana企业版与开源版在安装流程、插件管理和功能限制等方面的差异,特别针对离线部署场景提供实用技巧。通过实测数据源支持、权限管理等核心功能,帮助企业用户做出明智选择,同时详细介绍离线安装和插件签名验证等关键操作。

weixin_29313817的博客 104

SAP交货单过账避坑指南:序列号处理、Buffer清理与BAPI提交回滚的那些事儿

本文深入解析SAP交货单过账中的序列号处理、Buffer清理与BAPI提交回滚等关键问题,提供WS_DELIVERY_UPDATE和BAPI_OUTB_DELIVERY_CONFIRM_DEC的实战优化方案。通过详细的技术分析和最佳实践,帮助开发者避免常见陷阱,提升交货单处理的稳定性和效率。

weixin_31155097的博客 431

MT4提示警示return value&nbs…

问题1:MT4提示警示return value of 'OrderClose' should be checked 代码编程不够严谨的警告,非代码错误。不会影响你EA的运行。新版的MQL4对于订单类函数语句要求函数的返回值要明确,否则会出现此种警告。  orderclose();  orderselect();    ordersend();    OrderDelete(OrderTic

bluewater的专栏 4487

Ubuntu操作系统等保测评指南

Ubuntu操作系统等保测评指南

qq_40181198的博客 7026

针对在校大学生的C语言入门学习——编码示例

针对在校大学生的C语言入门学习——编码示例 学习编程最重要的就是练习,对于新手而言练习也是最痛苦的。编程没有思路、编译出错不会改等问题让很多人止步学习编程的大门。编程是需要训练的,训练就要讲究方法。方法不外乎“循序渐进”四个字。今天我就拿一个非常常见的编程入门习题带大家分析一下,希望能够帮助大家成功开启学习编程的大门。 这次我使用的编译器是GCC 4.6.3,向大家介绍编译器版本是因为后面我会和大家分享一下如何解决编译报错问题。不同的编译器版本对于同一个错误报错可能有一些差别,但是差别不大。 练习 题

seamancsdn的博客 2053

Openwifi 开源项目解读(一)

Openwifi wifi 80211 无线网卡 基带 FPGA linux 驱动 开源

2万+

【系统分析师】第6章-基础知识:企业信息化(核心总结)

企业信息化是数字化转型的核心,涵盖战略规划、技术应用和实施路径等方面。关键内容包括ERP、CRM、SCM等系统的定义与实施,以及数据仓库、商业智能等技术的应用。备考系统分析师需掌握信息化战略规划方法(如BSP、SDP)、系统建模工具,并能分析解决信息孤岛等问题。论文可围绕ERP实施、数据仓库应用等主题展开。企业信息化面临组织变革、技术选型等挑战,但能显著提升运营效率和竞争力。

数据知道的博客 6933

设计稿结构化解析:让大模型真正读懂测试需求

测试用例自动生成本质上是将模糊的设计意图转化为精确可执行逻辑的过程。其核心原理在于弥合设计稿与代码之间的语义鸿沟——而非简单调用大模型API。技术价值体现在通过结构化解析(如Figma JSON、Axure XML)提取字段约束、状态流转和业务规则,显著提升用例覆盖率与准确率。典型应用场景包括CI/CD前置门禁、缺陷驱动再生、跨端一致性验证等。实践表明,高质量结构化上下文比模型参数规模更能决定效果,尤其在边界值覆盖与Mock适配等关键环节。本文聚焦设计稿结构化解析与语义增强,结合CodeLlama、Deep

cuiji1279的博客 712

【路径规划】基于matlab蚁群算法机器人栅格地图最短路径规划【含Matlab源码 4590期】

基于matlab蚁群算法机器人栅格地图最短路径规划 完整代码,包运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 1276

令人困惑的return by value (转)

令人困惑的return by value (转)[@more@] 问题从这里开始。class X;const X operator+( const X& x1, const X& x2 );X foo(){r...

circularr9834的博客 304

Q3D提取PCB走线RLCG参数

介绍一种提取PCB走线寄生电容和寄生电感的方法

sinat_15150363的博客 2917

15、远程操作水下航行器(ROV)的非线性控制系统设计

本文探讨了远程操作水下航行器(ROV)的非线性控制系统设计,重点介绍了多变量PID控制、改进的PD控制和滑模控制三种方法。详细阐述了各控制策略的原理、建模与仿真过程,并通过对比分析其在稳态误差、振荡、抖振及跟踪效果等方面的性能表现。文章还提出了针对不同控制方法的优化建议,并给出了选择合适控制策略的决策流程,为ROV高精度运动控制提供了系统性解决方案。

sun99的博客 156

SAP ABAP开发避坑:当函数没有Return参数时,如何优雅地获取Exception里的错误消息?

本文深入探讨了SAP ABAP开发中无Return参数函数如何精准捕获Exception消息的解决方案。通过分析典型困境、核心解决方案SWO_TEXT_FUNCTION_EXCEPTION的深度应用以及企业级异常处理框架设计,帮助开发者优雅处理异常消息,提升开发效率。特别适用于SAP技术层和业务层函数的异常处理场景。

weixin_30291791的博客 481

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

年后面试必备:95%错误率的9道面试题!

你好,我是田哥如果你试图用常识回答一个棘手的问题,你很可能会因为需要一些特定的知识而失败。大多数棘手的Java问题来自于令人困惑的概念,如函数重载和覆盖,多线程,掌握非常棘手,字符编码,检查与未检查的异常和Integer溢出等微妙的Java编程细节。回答棘手的Java问题最重要的是态度和分析思维,即使你不知道答案也会有所帮助。在这篇Java文章中,我们将看到下面几个Java问题,并且需要更多的Ja...

田维常 376

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Pybind11实战:从C++类到Python模块的完整避坑指南(附常见错误解析)

本文提供了一份完整的Pybind11实战指南,重点解决将C++类库封装为Python模块过程中的常见难题。文章详细解析了如何通过正确的项目结构、CMake配置避免“undefined symbol”等链接错误,并深入探讨了数据类型转换、内存管理及性能优化等核心问题,帮助开发者高效构建稳定的跨语言接口。

h3i4j的博客 890

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

C++20协程核心原理与实战:从生成器到异步任务实现

协程是一种能够暂停和恢复执行的函数,它通过用户态的轻量级切换机制,避免了传统多线程的上下文切换开销和回调地狱的复杂性。其核心原理在于编译器生成的状态机管理,使得程序能够在异步操作等待期间释放线程资源,从而提高并发性能。这一技术在服务器开发、异步I/O处理和高性能计算等场景中具有重要价值。通过C++20引入的co_await、co_yield等关键字,开发者可以构建高效的异步流程,例如实现生成器(Generator)进行惰性序列生成,或创建异步任务(Task)来管理复杂的异步操作链。本文以C++20协程为例,

weixin_30642869的博客 311

年后面试必备:95%错误率的9道面试题

如果你试图用常识回答一个棘手的问题,你很可能会因为需要一些特定的知识而失败。大多数棘手的Java问题来自于令人困惑的概念,如函数重载和覆盖,多线程,掌握非常棘手,字符编码,检查与未检查的异常和Integer溢出等微妙的Java编程细节。 回答棘手的Java问题最重要的是态度和分析思维,即使你不知道答案也会有所帮助。 在这篇Java文章中,我们将看到下面几个Java问题,并且需要更多的Java编程语言知识来正确回答它们。

yyaannnnnnnn的博客 167

在CodeMash 2012的“ Wat”演讲中提到的这些怪异JavaScript行为的解释是什么?

The 'Wat' talk for CodeMash 2012 basically points out a few bizarre quirks with Ruby and JavaScript

asdfgh0077的博客 365

C++20协程与线程安全队列:构建高性能并发编程新范式

并发编程是现代软件开发的核心挑战之一,它涉及多个任务同时执行以提高系统吞吐量和响应速度。其基本原理是通过线程、进程或协程等机制实现并行处理,关键技术包括同步原语、锁机制和无锁数据结构。在C++高并发场景下,传统回调模式容易导致代码结构混乱,而协程作为一种轻量级并发原语,允许以同步风格编写异步逻辑,显著提升代码可读性。线程安全队列则作为关键基础设施,确保多线程环境下数据的安全访问与高效传递。结合C++20协程的挂起恢复特性与线程安全队列的同步机制,开发者能够构建清晰、高效的任务调度系统,广泛应用于网络服务器、

weixin_33841503的博客 507

Python异常处理实战:从try-except到自定义异常的健壮编程指南

在编程实践中,异常处理是构建可靠软件的核心机制。其原理在于通过预定义或自定义的异常对象,在程序执行出现意外时中断正常流程,转而执行预设的错误恢复逻辑。这一机制的技术价值在于提升程序的容错性和健壮性,避免因局部错误导致整个系统崩溃。在应用场景上,无论是文件读写、网络请求、用户输入验证还是资源管理,都需要异常处理来确保稳定性。本文聚焦于Python中的`try...except`语法,深入剖析其**核心机制**与**实战策略**,涵盖从基础语法、异常类型精确捕获,到利用`else`和`finally`进行资源清

weixin_34331102的博客 413

Python 3.12 真值测试陷阱:5 个易混淆的 `bool()` 转换案例解析

本文深入解析Python 3.12中5个易混淆的`bool()`转换案例,包括空列表与含零元素的列表、字符串`"False"`的布尔转换、自定义类的`__bool__`与`__len__`方法冲突、NaN与浮点零的特殊情况以及`None`与未定义变量的区别。帮助开发者避免常见陷阱,写出更健壮的代码。

weixin_33694172的博客 342
上一篇: [深度探索C++对象模型](简体版)中的蛇足
下一篇: RTTI应用:let's cast
招RD和QA
博客等级 码龄26年 40粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值