简体   繁体   English

成员函数中的临时对象-C ++

[英]Temporaries in member functions - C++

After putting some code to work, I'm trying to optimize it. 将一些代码投入工作后,我正在尝试对其进行优化。 One thing that I'm trying to avoid is the creation of temporaries. 我要避免的一件事是创建临时对象。 Given a class 上一堂课

class foo{
   private:
     int a;
   public:
     foo(int sa):a(sa);
     ~foo(){}
    inline int multiply(int b) {return a*b;}//temporary?
};

The intel compiler is giving me the temporary created/reference temporary used here. 英特尔编译器给了我这里使用的临时创建/引用临时文件。 Is any temporary variable being created? 是否正在创建任何临时变量?

EDIT: edited the return type. 编辑:编辑了返回类型。 Also, I think that no temporary variable is being created in multiply, but the intel compiler gives me an error about that. 另外,我认为没有乘法会创建临时变量,但是intel编译器给我一个错误。

EDIT 2: After the requests below, here is a FULL code that the intel compiler v. 12 gives the error: 编辑2:在以下请求之后,这是intel编译器v.12给出错误的完整代码:

 #include <iostream>
 #include <complex>

 using namespace std;
 const double pi = 3.1415;
 const complex <double> I = (0.0,I);
 const complex <double> oneover2piI = (1.0 / (2.0 * pi * I));

  class foo{
     private:
       complex <double> a;
     public:
       foo(complex <double> sa):a(sa){}
       ~foo(){}
       inline complex <double> multiply(complex<double> b) 
       {return  a*sqrt(b);}
   };

The compilation line is 编译行是

  icc -g -O2 -w2 -debug parallel -Wcheck -Weffc++ -mp -fp-stack-check -wd981 -wd2015 -wd1418  test.cpp -o  test

And the resulting warning is 结果警告是

  test.cpp(7): remark #383: value copied to temporary, reference to temporary used
  const complex <double> oneover2piI = (1.0 / (2.0 * pi * I));
                                         ^

The question was to understand what the compiler is balking at, and not to be hanous. 问题是要了解编译器在做什么,而不是太讨厌。

Thanks! 谢谢!

Don't worry about it. 不用担心

What you are doing is called "premature micro-optimization," and it is the root of much evil . 您正在做的事情被称为“过早的微观优化”,这是许多邪恶根源

It is also largely futile to try to micro-optimize 尝试进行微优化在很大程度上也是徒劳的

  1. micro-optimization without first profiling your code and identifying the places that need to be optimized is a complete waste of time. 无需先对代码进行性能分析并确定需要优化的位置,就可以进行微优化,这完全是在浪费时间。 You might end up shaving picoseconds off a routine that takes millions of picoseconds. 可能最终将一个耗时数百万皮秒的例程减少了皮秒。 Why bother? 何必呢?

  2. The compiler will optimize you code far better than you can. 编译器将大大优化您的代码。 MicroSoft for example has a team of people whose only job is to work on the optimizer. 例如,MicroSoft拥有一群人,他们的唯一工作就是在优化器上工作。 They are very smart people, working all day every day finding ways to optimize your code. 他们是非常聪明的人,每天整天都在努力寻找优化代码的方法。 In this case, the temporaries will often be optimized away. 在这种情况下,临时人员通常会被优化掉。 Let them do their thing. 让他们做自己的事。 They are better at it than you. 他们比你更好。

  3. micro-optimizations often come at the cost of harder to understand code. 微观优化通常以难以理解的代码为代价。 Code that is harder to understand is much more prone to having defects. 难以理解的代码更容易出现缺陷。 Those 4 picoseconds you saved are worthless if your function returns "fA@#zzzzzzz" instead of "foo". 如果您的函数返回“ fA @#zzzzzzzzz”而不是“ foo”,则保存的这4皮秒毫无价值。

First, select the correct algorithms for your task. 首先,为您的任务选择正确的算法。 Then write good, robust code that implements those algorithms. 然后编写实现这些算法的良好,健壮的代码。 Profile in release mode second. 概要文件处于释放模式。 Guided by the profiler, find the places that really need to be optimized, if there are any. 在分析器的指导下,找到确实需要优化的位置(如果有的话)。 Then optimize. 然后优化。

This doesn't really answer your question (I'm not sure where the temporary variable is created myself), but in general, creating temporary primitive variables will not save any speed, because the only difference is the stack space used -- so whether the stack pointer is incremented by 4 bytes or 8 bytes is irrelevant to the speed of your program, unless there's a page fault (which is very unlikely). 这并不能真正回答您的问题(我不确定自己在哪里创建临时变量),但是总的来说,创建临时原始变量不会节省任何速度,因为唯一的区别是所使用的堆栈空间-因此是否除非有页面错误(这种可能性很小),否则堆栈指针将增加4字节或8字节与程序的速度无关。 So you're unlikely to see any performance benefits with anything like this, especially if the compiler optimizes your code by putting variables in registers. 因此,您不太可能看到类似这样的性能提升,特别是如果编译器通过将变量放入寄存器来优化代码时。

I think the compiler issues a warning because it translates: 我认为编译器会发出警告,因为它会翻译:

const complex <double> oneover2piI = (1.0 / (2.0 * pi * I));

to invoke a default copy constructor: 调用默认的复制构造函数:

Object::complex<double>(const complex<double>&)

which takes a reference of the temporary object as the argument, and makes a shallow copy (that results in data sharing if you use pointers) of the object. 它以对临时对象的引用作为参数,并对该对象进行浅表复制(如果使用指针,则将导致数据共享)。 Basically this data sharing + temporary lifespan is the core of the problem. 基本上,这种数据共享+临时寿命是问题的核心。 Take a look at the "academic" class below. 看看下面的“学术”课程。

#include<iostream>

class A
{

public:

  A()
    :attribute(new char[10]) {}

  ~A()
  {
    std::cout << "d'ctor" << std::endl; 
    if(attribute){
      delete [] attribute;
      attribute = 0;
    }
  }

  A& operator +(const char& n)
  {
    //do some operation
    return *this;
  }

  void reset_attribute(char *new_ptr)
  {
    attribute = new_ptr;
  }

private:

  char *attribute;
};

int main()
{
  {//new scope to invoke destructors
    A b;
    A c = b;
    b.reset_attribute(new char[10]);
  }//no problem in this scope

  A a = (A()+2);//problem with a temporary object

  return 0;
}

the cygwin output: cygwin的输出:

$ ./a.exe
d'ctor //this is from b or c
d'ctor //this is from b or c
d'ctor //this is from temporary
d'ctor //this is from a
Aborted (core dumped)

The delete operation has been executed twice on the same pointer, because it was shared between the temporary object and a . delete操作已在同一指针上执行了两次,因为它在临时对象和a之间共享。

a*b creates a new temporary. a*b创建一个新的临时文件。 Whatever the hell the rest of your question text means, I have no idea, but in as far as you use the word "temporary", one is created. 无论问题文本的其余部分到底意味着什么,我都不知道,但是就您使用“临时”一词而言,就创建了一个。

Given the code you claim the compiler is complaining about...the compiler should not be complaining. 给定您声称的代码,编译器在抱怨...编译器不应在抱怨。 Since you've not included the real error...I have absolutely no clue why you think it's complaining about what you claim its complaining about. 既然您还没有包含真正的错误...我绝对不知道为什么您认为它在抱怨您所声称的抱怨。

Edit: 编辑:

Given that you claim the code in your edit is the REAL code causing the error you also finally quoted, my bet is that the compiler has been completely confused by the line BEFORE the one it's complaining about: 假设您声称编辑中的代码是导致您最后引用的错误的REAL代码,那么我敢打赌,编译器已经被抱怨的那一行完全弄糊涂了:

const complex <double> I = (0.0,I);

I don't know what you indend for that to do, but it don't look legal to me. 我不知道您打算这样做,但是对我来说这并不合法。

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

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