Оптимизация копирования и оптимизации возвращаемого значения в сравнении с конструктором копирования

Я читал о том, как оптимизация копирования и возвращаемое значение могут улучшить скорость, избегая обращений к конструктору копирования объектов. Я понимаю, как работают механизмы, но мне было интересно, не может ли это привести к программам, которые ведут себя не так, как следовало ожидать.

По сути, мой вопрос таков; что произойдет, если мы напишем конструктор копирования, чтобы не создавать объект, который является копией другого объекта? Другими словами, что если

AClass original;
AClass copy ( original );
// copy == original -> false

Скажем, например, у нас был такой класс:

// AClass.hpp

struct AClass
{
static int copyCount;
int copyNumber;

AClass():copyNumber(0){}
AClass( AClass const& original ):copyNumber(++copyCount){} // I think this is the signature for the copy constructor
};// AClass.cpp

int AClass::count ( 0 );

Это, очевидно, ужасное поведение, чтобы положить в класс, я не говорю, что я бы сделал что-то подобное. Суть, однако, стоит; что если мы полагаемся на побочные эффекты копии? В этом примере мы отслеживаем, сколько копий мы сделали. Я ожидаю, что оптимизация не должна влиять на работу программы. Однако копирование elision может привести к сбою следующего кода:

// Main.cpp

AClass MakeAClass()
{
return AClass();
}

int main()
{
AClass copy ( MakeAClass() );

if ( AClass::copyCount == 1 )
{
return 0;
}
else
{
return -1;
}
}

Это может вернуть 0, когда я строю в режиме отладки без оптимизаций, но внезапно завершится неудачей, когда я включу оптимизации, и возврат из MakeAClass будет помещен непосредственно в копию, пропуская конструктор копирования.

Есть ли проверка, когда компилятор пытается эти оптимизации искать побочные эффекты? Неправильно ли ожидать, что код выполнит копирование, когда вы запрашиваете копию?

0

Решение

Да. Elision Copy может изменить поведение вашего кода, если ваш конструктор копирования (или ваш конструктор перемещения или ваш деструктор) имеет побочные эффекты.

В этом весь смысл. Если бы это не могло изменить поведение, не было бы никакой причины упоминать это в стандарте. Оптимизации, которые не меняют поведение, уже охватываются правилом «как будто». (1.9 / 1) То есть:

Семантические описания в этом международном стандарте определяют
параметризованная недетерминированная абстрактная машина. Этот международный
Стандарты не предъявляют никаких требований к структуре соответствия
Реализации. В частности, им не нужно копировать или эмулировать
структура абстрактной машины. Скорее, соответствующие реализации
должны эмулировать (только) наблюдаемое поведение абстрактного
машина
как объяснено ниже.

Исключение копирования прямо указано в стандарте именно потому, что оно потенциально нарушает это правило.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]