简体   繁体   English

在C ++中意外创建临时对象的方法?

[英]Ways to accidentally create temporary objects in C++?

Years ago I believed that C was absolutely pure compared to C++ because the compiler couldn't generate any code that you couldn't predict. 多年前我相信C与C ++相比绝对纯净,因为编译器无法生成任何你无法预测的代码。 I now believe counter examples include the volatile keyword and memory barriers (in multiprocessor programming or device drivers for memory-mapped hardware devices, where plain assembly language would be even more pure than the optimizations of a C compiler). 我现在相信反例包括volatile关键字和内存屏障(在多处理器编程或内存映射硬件设备的设备驱动程序中,其中普通汇编语言甚至比C编译器的优化更纯粹)。

At the moment I'm trying to enumerate the unpredictable things a C++ compiler can do. 目前我正在尝试枚举C ++编译器可以执行的不可预测的事情。 The main complaint that sticks in my mind about C++ is that the compiler will implicitly instantiate temporary objects, but I believe these cases can all be expected. 关于C ++的主要抱怨是编译器将隐式实例化临时对象,但我相信这些情况都可以预期。 The cases I'm thinking of are: 我正在考虑的案例是:

  • when a class defines a copy constructor for a type other than itself, without using the explicit keyword 当一个类为自己以外的类型定义一个复制构造函数时,不使用explicit关键字
  • when a class defines an overloaded conversion operator: operator () 当一个类定义一个重载的转换运算符时: operator ()
  • when a function accepts an object by value instead of by reference 当函数通过值而不是引用接受对象时
  • when a function returns an object by value instead of by reference 当函数按值而不是按引用返回对象时

Are there any others? 还有其他人吗?

I suppose "unpredictable" means "something in accordance with the standard but different from what the programmer expects when writing code", right? 我认为“不可预测”意味着“符合标准的东西,但与程序员编写代码时的期望不同”,对吧?

I guess you can see from the code where objects are being instantiated or copied, even if it's maybe not obvious. 我想你可以从代码中看到对象被实例化或复制的情况,即使它可能并不明显。 It might be hard to understand though. 但可能很难理解。

Some stuff is just implemented in certain ways by (all?) compiler vendors, but it could be done differently. 有些东西只是由(所有?)编译器供应商以某种方式实现,但它可以以不同的方式完成。 Eg, late binding (aka. calling an overloaded, virtual method) is usually implemented using function pointers in the background. 例如,后期绑定(也称为调用重载的虚拟方法)通常使用后台的函数指针来实现。 This is maybe the fastest way doing it, but I suppose it could be done differently and that would be unexpected. 这可能是最快的方式,但我想它可以以不同的方式完成,这将是意想不到的。 I don't know any compiler though that does it differently. 我不知道任何编译器,但它有不同的方式。

Lots of stuff is unexpected in the sense that C++ is overly complex - hardly anybody understands the full language. 在C ++过于复杂的意义上,很多东西都是出乎意料的 - 几乎没有人理解完整的语言。 So unexpected also depends on your knowledge. 所以意外也取决于你的知识。

12.2 Temporary objects 12.2临时物体

1 Temporaries of class type are created in various contexts: binding an rvalue to a reference (8.5.3), returning an rvalue (6.6.3), a conversion that creates an rvalue (4.1, 5.2.9, 5.2.11, 5.4), throwing an exception (15.1), entering a handler (15.3), and in some initializations (8.5). 1类型的临时类型在各种上下文中创建:将右值绑定到引用(8.5.3),返回右值(6.6.3),创建右值的转换(4.1,5.2.9,5.2.11,5.4) ),抛出一个异常(15.1),进入一个处理程序(15.3),并在一些初始化(8.5)中。

4 There are two contexts in which temporaries are destroyed at a different point than the end of the fullexpression. 4有两种情况,临时表演在不同于完整表达结束时被摧毁。

In fact I suggest take a look at the entire 12.2 事实上我建议看看整个12.2

At the moment I'm trying to enumerate the unpredictable things a C++ compiler can do. 目前我正在尝试枚举C ++编译器可以执行的不可预测的事情。 The main complaint that sticks in my mind about C++ is that the compiler will implicitly instantiate temporary objects, but I believe these cases can all be expected. 关于C ++的主要抱怨是编译器将隐式实例化临时对象,但我相信这些情况都可以预期。

The compiler does not create temporaries implicitly -- it obeys the standard. 编译器不会隐式创建临时文件 - 它遵循标准。 Unless, of course, when you invoke undefined behavior. 当然,除非您调用未定义的行为。 Note, that there is something called copy-elision and return value optimization which may actually reduce the number of temporaries that would otherwise be created. 注意,有一种称为复制省略和返回值优化的东西,它实际上可以减少否则将被创建的临时数量。

An interesting link about common pitfalls related to this subject: 关于此主题的常见陷阱的一个有趣链接:

http://www.gotw.ca/gotw/002.htm http://www.gotw.ca/gotw/002.htm

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM