Разрешено ли копирование/перемещение при возврате * и объекта?
Посмотрите на этот код:
#include <stdio.h>
struct Foo {
Foo() { }
Foo(const Foo &) { printf("copy\n"); }
Foo(Foo &&) { printf("move\n"); }
};
Foo getFoo() {
Foo f;
return *&f;
}
int main() {
getFoo();
}
С++ 14 Standard говорит (12.8/31), что разрешено копирование/перемещение:
в операторе return в функции с возвращаемым типом класса, когда выражение - это название энергонезависимого автоматического объекта (кроме параметр функции или catch-clause) с тем же cv-unquali fiified тип как возвращаемый тип функции, операция копирования/перемещения может быть опущено путем создания автоматического объекта непосредственно в функция возвращает значение
В моем примере выражение return не является именем, поэтому я не думаю, что разрешение разрешено.
Я проверил GCC/clang/MSVC, и пока clang/MSVC не выдаёт копию, GCC делает. Здесь GCC нарушает стандарт?
Ответы
Ответ 1
Во-первых, правило "as-if" здесь не применяется, потому что ваши конструкторы копирования и перемещения имеют побочные эффекты (они выполняют IO). Таким образом, GCC не может перемещать копию/перемещение под этим заголовком.
С быстрым взглядом я не вижу никаких других формулировок, которые позволяли бы эликсировать, поэтому я думаю, что это ошибка в GCC. С другой стороны, мне бы очень хотелось, чтобы стандарт расширил рамки копирования/перемещения, чтобы включить этот случай. (В минимальном примере, который вы представили, я не вижу, как это вызовет проблемы - я полагаю, у вас есть большой пример, где он это делает.)