警惕 C++ 中的隐式类型转换

开发 前端
我在研究一个代码中的栈溢出问题。为了减小栈帧的大小,我尽可能多地删除了局部变量,但仍有很多栈空间无法解释。除了局部变量、参数、保存的寄存器和返回地址之外,栈上还有什么其他的东西呢?

今天文章的主题灵感来自客户的一个问题:

我在研究一个代码中的栈溢出问题。为了减小栈帧的大小,我尽可能多地删除了局部变量,但仍有很多栈空间无法解释。除了局部变量、参数、保存的寄存器和返回地址之外,栈上还有什么其他的东西呢?

我的回答是,嗯,还有结构化(SEH)的异常处理信息,但这通常不会占用太多栈空间,因此不会成为”大量”神秘栈使用的来源。

我的猜测是,代码正在生成大量大型 C++ 临时对象。请考虑以下程序片段:

有人会问了:”这段代码是如何编译的?函数Foo想要一个BigBuffer,而不是一个整数!” 然而编译它确实如此。

这是因为编译器使用 BigBuffer 构造函数作为转换器。换句话说,编译器插入了以下临时变量:

这样做是因为,只接受一个参数的构造函数有两个目的:它可以用作传统的构造函数(正如我们在 BigBuffer temp(3) 中看到的那样),或者它可以用来提供从参数类型到构造类型的隐式转换。在本例中,BigBuffer(int) 构造函数被用作从 int 到 BigBuffer 的转换。

若要防止这种情况发生,请使用 explicit 关键字:

通过此更改, 对 Foo(3) 的调用会引发编译器错误:

总结

通过今天的文章,我终于理解了在何种情况下需要在构造函数上加 explicit 。
你呢?

责任编辑:武晓燕 来源: 今日头条
相关推荐

2023-09-22 09:04:00

C++编程

2010-02-04 16:47:04

C++隐式转换

2011-07-14 10:39:08

强制类型转换函数C++

2010-02-04 16:52:45

C++显式转换

2009-09-04 10:49:19

C#隐式转换

2009-09-01 10:49:28

C#具有隐式类型声明

2017-12-20 14:14:16

数据库MySQL数据类型

2016-12-20 16:35:52

NodeJSC++类型转换

2010-01-28 16:31:54

C++类型

2017-09-13 10:58:51

JavaScript转换规则

2016-12-07 11:23:52

NodeJSC++

2017-09-05 16:17:35

JavaScript运算转换

2019-09-28 22:41:18

OracleMySQL隐式数据

2010-01-20 09:54:27

C++数据类型

2010-02-03 11:11:18

C++类型转换

2009-08-26 15:39:08

C#隐式类型局部变量

2022-02-23 21:24:21

索引SQL字符

2023-12-12 08:50:22

MySQL隐式转换varchar

2009-07-21 13:54:55

Scala重载方法隐式转换

2011-07-20 13:34:37

C++
点赞
收藏

51CTO技术栈公众号