This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: gcc 3.0.1 & C++ ABI issues


>>>>> "Gabriel" == Gabriel Dos Reis <gdr@codesourcery.com> writes:

> Jason Merrill <jason_merrill@redhat.com> writes:
> | IMO, optimizing this case is not important anyway; who passes complex
> | objects by value?

> Numericists :-)  (Note also that B. Stroustrup in TC++PL3 encourages
> passing by value object of concrete classes such as complex<>).
> Passing "small" objects such as complex<> by value is seen to be
> superior to passing by const reference.

True.  Actually, I meant complex in the more general sense...

OK, I'm convinced that optimizing this sort of thing is desirable, and that
it would require a tree optimization pass.  I still don't think the current
standard allows it, but we might still want to bend the rules for
numericists.

FWIW, the old, more general wording was:

15Whenever a class object is copied and the original object and the copy
  have  the  same  type, if the implementation can prove that either the
  original object or the copy will never again be  used  except  as  the
  result  of  an implicit destructor call (_class.dtor_), an implementa-
  tion is permitted to treat the original and the copy as two  different
  ways  of  referring  to the same object and not perform a copy at all.
  In that case, the object is destroyed at the later of times  when  the
  original   and   the  copy  would  have  been  destroyed  without  the
  optimization.9)
  _________________________
  9) Because only one object is destroyed instead of two, and  one  copy
  constructor  is  not executed, there is still one object destroyed for
  each one constructed.

  [Example:
          class Thing {
          public:
                  Thing();
                  ~Thing();
                  Thing(const Thing&);
                  Thing operator=(const Thing&);
                  void fun();
          };
          void f(Thing t) { }
          void g(Thing t) { t.fun(); }

          int main()
          {
                  Thing t1, t2, t3;
                  f(t1);
                  g(t2);
                  g(t3);
                  t3.fun();
          }
  Here t1 does not need to be copied when calling f because f  does  not
  use  its  formal parameter again after copying it. Although g uses its
  parameter, the call to g(t2) does not need to copy t2  because  t2  is
  not used again after it is passed to g.  On the other hand, t3 is used
  after passing it to g so calling g(t3) is required to copy t3.  ]

The optimization was restricted to temporaries and the NRVO in the October
'97 working paper.  I don't rember the example that motivated this change;
perhaps the example above was thought excessive.  I would think that
treating parameters as temporaries in our earlier example would make sense
in the context of inlining; I would expect them to look about the same in
the tree structure.

Jason


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]