LINUX.ORG.RU

Стандарт С++ гарантирует, что приведенный ниже код рабочий?


0

1
#include <stdio.h>

struct Foo {
  Foo() {
    printf("ctor\n");
  }
  Foo(const Foo &) {
    printf("copy ctor\n");
  }
  ~Foo() {
    printf("dctor\n");
  }

  void call() const {
    printf("cal\n");
  }
};

Foo return_local_object_1() {
  Foo foo;
  return foo;
}

Foo return_local_object_2() {
  return return_local_object_1();
}

int main(int argc, char* argv[]) {
  const Foo &foo = return_local_object_2();
  foo.call();
}

И будет ли хоть раз скопирован объект foo? Код компилируется, запускается, но в стандарте не могу найти секцию, которая описывает это поведение. Если вы хорошо знакомы со стандартом, не могли бы сказать параграф, где это описано?

Спасибо.

Не то не другое поведение не гарантируется

Уже натыкались на эти грабли

namezys ★★★★
()

гарантирует, что рабочий, но не гарантирует отсутствие копирования.

про RVO тебе уже написали, почитай

anonymous
()
Ответ на: комментарий от anonymous

> про RVO тебе уже написали, почитай

Да, да ребят, спасибо! Так и правда нельзя делать.

ama1185
() автор топика
Ответ на: комментарий от JackDaniel

Сначала у меня был нормальный код

Foo return_local_object_2() {
  Foo foo;
  return foo;
}

int main(int argc, char* argv[]) {
  const Foo &foo = return_local_object_2();
  foo.call();
}

затем изменил функцию `return_local_object_2` так, чтобы она возвращала не свой локальный объект, а результат `return_local_object_1` и все, уже Undefined behavior (на вызывающий код просто забыл посмотреть).

Жесть вообще :(

ama1185
() автор топика
Ответ на: комментарий от ama1185

> Сначала у меня был нормальный код

в каком месте он нормальный? в чем тут сакральный смысл «const Foo &foo»?

aho
()
Ответ на: комментарий от aho

> в чем тут сакральный смысл «const Foo &foo»?

Если написать просто 'Foo foo', то 100% при возврате из функции будет 1 копирование объекта foo. C 'const Foo &foo' и RVO копирования не будет.

ama1185
() автор топика
Ответ на: комментарий от ama1185

> Если написать просто 'Foo foo', то 100% при возврате из функции будет 1 копирование объекта foo. C 'const Foo &foo' и RVO копирования не будет.

на лицо полное непонимание работы кода и этого самого RVO, ну возьми напиши просто 'Foo foo' - и сравни, будет точно также

aho
()
Ответ на: комментарий от aho

А и правда. Спасибо, буду разбираться.

ama1185
() автор топика
Ответ на: комментарий от aho

Но если компилятор не сделает RVO, то ведь c вариантом 'const &' будет на одно копирование меньше? Ведь правильно?

ama1185
() автор топика
Ответ на: комментарий от ama1185

> Но если компилятор не сделает RVO, то ведь c вариантом 'const &' будет на одно копирование меньше? Ведь правильно?

RVO работает не в main, RVO позволяет не копировать foo из return_local_object_1 еще раз в стек, в main ты уже имеешь временный объект «на руках», и хоть ты напишешь Foo f = , хоть const Foo& f =, ничего от этого не изменится

aho
()
Ответ на: комментарий от anonymous

гарантирует, что рабочий

Нашел в стандарте, почему именно так (пункт 12.2 Temporary objects):

[Example:

class C {
// ...
public:
C();
C(int);
friend C operator+(const C&, const C&);
~C();
};
C obj1;
const C& cr = C(16)+C(23);
C obj2;

the expression C(16)+C(23) creates three temporaries. A first temporary T1 to hold the result of the expression C(16), a second temporary T2 to hold the result of the expression C(23), and a third temporary T3 to hold the result of the addition of these two expressions. [...] The temporary T3 bound to the reference cr is destroyed at the end of cr’s lifetime [...] ]

ama1185
() автор топика
Ответ на: комментарий от ama1185

Отличный язык. И почему фанатики С++ всё время говорят, что он «быстрый, как Си»? В Си есть полная детерминированность, а здесь - шиш

anonymous
()

К слову - можно легко доказать, что копирование потенциально выполняется. Для этого досточно сделать конструктор копирования закрытым и наслаждаться сообщениями об ошибке.

Vamp
()
Ответ на: комментарий от anonymous

А полная детерменированность никому не нужна. ;)

Vamp
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.