powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Что происходит ?
23 сообщений из 23, страница 1 из 1
Что происходит ?
    #39793551
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
struct T {
   int a;
}


T getT() {
    T t{};
    return t;
}


void main() {
  T t = getT(); // Что произошло c результатом getT() здесь ?
  std::cout << t.a << std::endl;


  getT(); // Что произошло c результатом getT() здесь ?
  T t1 = getT(); // Что произошло c результатом getT() здесь ?
  std::cout << t1.a << std::endl;

}
...
Рейтинг: 0 / 0
Что происходит ?
    #39793570
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
T t = getT();


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

В данном случае возвращаемое значение (rvalue) улетает в никуда
Код: plaintext
1.
getT();
...
Рейтинг: 0 / 0
Что происходит ?
    #39793585
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum
Код: plaintext
1.
T t = getT();


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

В данном случае возвращаемое значение (rvalue) улетает в никуда
Код: plaintext
1.
getT();




T t = std::move(getT());

?
...
Рейтинг: 0 / 0
Что происходит ?
    #39793586
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--В данном случае возвращаемое значение (rvalue) улетает в никуда

В никуда это не ответ


Что происходит ?
...
Рейтинг: 0 / 0
Что происходит ?
    #39793587
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Что происходит ?
    #39793590
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semen--В данном случае возвращаемое значение (rvalue) улетает в никуда

В никуда это не ответ
Что происходит ?

getT возвращает значение которое никто не принимает, следовательно тут будет все зависеть от компилятора
Если сборка производится с оптимизирующими флагами и внутри getT никто не выделяет память из кучи, то компилятор скорее всего вообще удалит данный вызов, как мусорный и не меняющий саму суть кода.

В debug режиме компилятор может создать rvalue копию значения, которая будет разрушена при выходе из области видимости, т.е. }. Но поскольку обратится к ней нет никакой возможности, debug компилятор, может также выкинуть эту инструкцию, просто вызовет getT, но возвращаемое значение соптимизирует.
...
Рейтинг: 0 / 0
Что происходит ?
    #39793592
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Что происходит ?
    #39793601
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
std::move это страшная покрытая мраком мгла - которая ничуть не более чем каст

Реально есть память А, есть память B и дальше мы каким то образом переносим данные из одной части в другую

Вот у нас стек

1 <----- зашли в getT()
2 выделили память под T;
3 <------ вышли из getT();

Я так понимаю, что при определенных настройках компилятора - мы заиспользуем прямо ту память которая на стеке была зерезервирована в точке 2

Однако при выходе из метода ее уже может не существовать (все таки стек)

Вот и хочется понять экспертизу данного поведения

При каких ключиках и настройках (или других факторах) мы получим адрес ровной той памяти что выделилась на стеке внутри метода - а при каких на стеке создадут копию и как то переместят туда ранее созданное в методе добро (как это будут делать при помощи std::move или copy конструктора) - дело десятое.
...
Рейтинг: 0 / 0
Что происходит ?
    #39793609
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenВот и хочется понять экспертизу данного поведения

Ну так --save-temps в руки и смотри на порождаемый ассемблер до просветления.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Что происходит ?
    #39793624
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenstd::move это страшная покрытая мраком мгла - которая ничуть не более чем каст

Реально есть память А, есть память B и дальше мы каким то образом переносим данные из одной части в другую

Вот у нас стек

1 <----- зашли в getT()
2 выделили память под T;
3 <------ вышли из getT();
...

Может так быть:
1 выделили память под T;
2 <----- зашли в getT()
3 <------ вышли из getT();

Со стеком полный порядок.
...
Рейтинг: 0 / 0
Что происходит ?
    #39793656
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakovsemen.s.semenВот и хочется понять экспертизу данного поведения

Ну так --save-temps в руки и смотри на порождаемый ассемблер до просветления.


Ох уж эти RTFM и поди погугли эксперты :)

Хочется информации от умных людей )
...
Рейтинг: 0 / 0
Что происходит ?
    #39793662
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum,

спасибо


извиняюсь если был грубоват - характер.
...
Рейтинг: 0 / 0
Что происходит ?
    #39793675
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Копирование происходит в данном случае
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
T getT() {
	T t{};
	printf("%p getT()\n", &t);
	return t;
};


void test_T() {
	T t = getT(); // Что произошло c результатом getT() здесь ?
	printf("%p test_T()\n", &t);
};


Выводит
Код: plaintext
1.
000000000030FEE0 getT()
000000000030FEE4 test_T()

MSVC 2017
...
Рейтинг: 0 / 0
Что происходит ?
    #39793693
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tsemen.s.semenstd::move это страшная покрытая мраком мгла - которая ничуть не более чем каст

Реально есть память А, есть память B и дальше мы каким то образом переносим данные из одной части в другую

Вот у нас стек

1 <----- зашли в getT()
2 выделили память под T;
3 <------ вышли из getT();
...

Может так быть:
1 выделили память под T;
2 <----- зашли в getT()
3 <------ вышли из getT();

Со стеком полный порядок.

Теоретически таких T внутри метода может быть масса

Заранее выделить в стеке не получится
...
Рейтинг: 0 / 0
Что происходит ?
    #39793715
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenDima Tпропущено...


Может так быть:
1 выделили память под T;
2 <----- зашли в getT()
3 <------ вышли из getT();

Со стеком полный порядок.

Теоретически таких T внутри метода может быть масса

Заранее выделить в стеке не получится
Почему? ИМХО это просто шаманство на уровне компиляции, компилятор видит весь код и в разных случаях один и тот же код getT() скомпилирует по-разному.

Своими словами мне сложно объяснить, в этой книге неплохо описаны принципы работы std::move
...
Рейтинг: 0 / 0
Что происходит ?
    #39793721
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да причем тут вообще std::move
...
Рейтинг: 0 / 0
Что происходит ?
    #39793724
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TСвоими словами мне сложно объяснить

Это говорит об отсутствии четкого и ясного понимания и экспертизы
...
Рейтинг: 0 / 0
Что происходит ?
    #39793733
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenDima TСвоими словами мне сложно объяснить

Это говорит об отсутствии четкого и ясного понимания и экспертизы
Я с std::move не разбирался, как понял он и так работает в stl.

А данном коде просто копирование происходит. Может код понятнее будет если заменить T на int. Разницы никакой.
...
Рейтинг: 0 / 0
Что происходит ?
    #39793806
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
#include <iostream>

struct A {
public:
  void t() {}

  A() {}

  A(A &t) { std::cout << "std::copy" << std::endl; }

  A(A &&t) { std::cout << "std::move" << std::endl; }

  A &operator=(A &&data) noexcept {}
};

void point(A t) {}

A getA() {
  A a{};
  return a;
}

int main() {
  // A a{};
  // point(std::move(a));
  // A b = std::move(a);

  A a = getA();

  a.t();
}
...
Рейтинг: 0 / 0
Что происходит ?
    #39793808
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
#include <iostream>

struct A {
public:
  void t() {}

  A() {}

  A(A &t) { std::cout << "std::copy" << std::endl; }

  A(A &&t) { std::cout << "std::move" << std::endl; }

  A &operator=(A &&data) noexcept {}
};

void point(A t) {}

A& getA() {
  A a{};
  return a;
}

int main() {
  // A a{};
  // point(std::move(a));
  // A b = std::move(a);

  A a = getA();

  a.t();
}
...
Рейтинг: 0 / 0
Что происходит ?
    #39793833
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semen,

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

Если функция вызывается без присвоения в переменную, то происходит все тоже самое, только переменная не видна программисту и освобождается после вызова.

Все вышеописанное происходит в любом случае даже без оптимизаций.

Есть еще оптимизация RVO.
Если внутри функции создается переменная, которая потом возвращается, то компилятор имеет право не создавать отдельную переменную и потом копировать ее в возвращаемое значение, а создать эту переменную сразу в памяти выделенной под возвращаемое значение.
...
Рейтинг: 0 / 0
Что происходит ?
    #39793843
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поправка, то что я описал - это NRVO.
А RVO работает на вызывающей стороне, когда возвращаемое значение создается в переменной куда присваивается, а не во временной с копированием в переменную.
...
Рейтинг: 0 / 0
Что происходит ?
    #39793844
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskysemen.s.semen,

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

Если функция вызывается без присвоения в переменную, то происходит все тоже самое, только переменная не видна программисту и освобождается после вызова.

Все вышеописанное происходит в любом случае даже без оптимизаций.

Есть еще оптимизация RVO.
Если внутри функции создается переменная, которая потом возвращается, то компилятор имеет право не создавать отдельную переменную и потом копировать ее в возвращаемое значение, а создать эту переменную сразу в памяти выделенной под возвращаемое значение.

Спасибо за ясную экспертизу
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Что происходит ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]