The compiler destroys the optimized object (never created)

I simplified my code to the root of the problem:

//==============================================================================
// PRE-DEFINITIONS

#define GIVE_ME_ODD_BEHAVIOUR true

//==============================================================================
// INCLUDES

#include <iostream>

//==============================================================================
// TYPES

//------------------------------------------------------------------------------
template<typename T> struct X {

  T data;

  X() : data(0)
  { std::cout << "X construction @ " << this     << std::endl; }

  template<typename TT>
  X(const X<TT> & other) : data(other.data)
  { std::cout << "X construction @ " << this << " from " << &other << std::endl; }

  ~X()
  { std::cout << "X destruction  @ " << this << std::endl; }

  template<typename TT>
  void Copy(const X<TT> & other)
  { std::cout << "X copy         @ " << this << " from " << &other << std::endl; }

};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template<typename T>
X<double> XConversion(const X<T> & other)
{

#if GIVE_ME_ODD_BEHAVIOUR

  return X<double>(other);

#else

  X<double> d;
  d.Copy(other);

  return d;

#endif

}


//==============================================================================
// MAIN

int main()
{

  X<double> d;
  X<int>    i;

  std::cout << std::endl;

  d = XConversion(i);

  std::cout << std::endl;

  d = XConversion(d);         // !!!

  std::cout << std::endl;

  return 0;

}

which at

GIVE_ME_ODD_BEHAVIOUR true

gives the result:

X construction @ 0x23aa70
X construction @ 0x23aa60

X construction @ 0x23aa80 from 0x23aa60
X destruction  @ 0x23aa80

X destruction  @ 0x23aa90 // never created !!!

X destruction  @ 0x23aa60
X destruction  @ 0x23aa70

Sounds like an IT problem , but I did define ctor. I see a copy optimization point here, but:

  • Why does a copier destroy an object that it has optimized and thus never create?
  • How can I guarantee that this will not happen?

Additional Information:

I tried gcc 4.8.1 and C ++ Builder XE3, disable optimization, debug compilation, with the same result.

I tried to delete the template, for example

struct X {

  double data
  ...
  X(const X &)
  ...

};

but with the same result.

One way to solve this problem would be, for example, to make a private cctor and publish only the Copy method. But that would prevent me (anyone) from even returning the object from the function ...


Background:

, . , - . , . , ref . , , ref .

+4
1

, , , , ( , ( ) ... , )... see:

:

X(const X & other) : data(other.data)
{ std::cout << "X Copy construction @ " << this << " from " << &other << " as " << typeid(X).name() << std::endl; }


template<typename TT>
X(const X<TT> & other) : data(other.data)
{ std::cout << "X construction @ " << this << " from " << &other << " as " << typeid(TT).name() << std::endl; }

:

X construction @ 0x7fff3496c040
X construction @ 0x7fff3496c038

X construction @ 0x7fff3496c020 from 0x7fff3496c038 as i
X destruction  @ 0x7fff3496c020

X Copy construction @ 0x7fff3496c018 from 0x7fff3496c040 as 1XIdE
X destruction  @ 0x7fff3496c018

X destruction  @ 0x7fff3496c038
X destruction  @ 0x7fff3496c040

. ( clang, g++, )

+4

Source: https://habr.com/ru/post/1548490/


All Articles