Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
 
hiphone
13 / 13 / 3
Регистрация: 28.01.2012
Сообщений: 549
#1

Применение std::move к локальной переменной при возврате из функции - C++

06.07.2017, 14:53. Просмотров 505. Ответов 19
Метки нет (Все метки)

C++
1
2
3
4
5
Response HostHandler::notFound() const {
    Response resp;
    resp.status = 404;
    return std::move(resp);
}
Имеет ли это смысл?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.07.2017, 14:53
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Применение std::move к локальной переменной при возврате из функции (C++):

Чтение переменной несколькими std::thread - C++
Собственно, вопрос в заголовке темы. Можно ли прочитать одну переменную несколькими потоками одновременно? Именно прочесть, а не...

Применение IntToStr к переменной типа long. Несовпадение исходных и конечных значений - C++ Builder
Доброго времени суток. Даже не знаю, как коротко сформулировать вопрос, поэтому название дал теме несколько сумбурное. Имеется...

Присвоение локальной переменной статуса глобальной - C++ Builder
Есть 2 кнопки. 1-я должна генерировать случайный числа и записывать их в массив array. 2-я - выводить в лейбл наибольшее число с...

Исключение при вызове CRecordset::Move(n) - Visual C++
Товарищи! Не могу понять, в чем проблема. Используя ODBC , читаю таблицу Excel, записываю результат выборки в объект типа CRecordset,...

Можно ли из локальной переменной сделать глобальную? - Visual C++
Можно ли из локального переменного сделать глобальный? Если да, то как это сделать? Заранее спасибо))

Нелепая ошибка в локальной переменной - C++ WinAPI
И так: Пишу на Visual C++ под Winapi. Создал диалог, в него поместил локальную переменную: bool VCam=0; Создал кнопку. Привязал...

19
Nick Alte
Эксперт С++
1639 / 1011 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
09.07.2017, 11:07 #16
Цитата Сообщение от hoggy Посмотреть сообщение
у вас со здравым смыслом все в порядке?
Да, а тебе засчитано +1 очко хамства.
Цитата Сообщение от hoggy Посмотреть сообщение
с восприятием реальности как?
Нормально, тебе +1 хамства.

Цитата Сообщение от hoggy Посмотреть сообщение
вам выше код привели.
как RVO/NRVO идут лесом.
и конструктор становится наблюдаем.
Мне там выше привели пример, где побочные эффекты конструктора становятся видны, потому что обязаны.

Цитата Сообщение от hoggy Посмотреть сообщение
ассм выхлоп не нужен, что бы понимать:
мув ломает RVO/NRVO оптимизацию.
Асм нужен, чтобы понимать, что получается в итоге. Иначе можно закончить так, как ты: молясь на смесь стандарта и своих заблуждений и отвергая реальные факты.

Цитата Сообщение от hoggy Посмотреть сообщение
да. всегда.
Проверим:
Код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <utility>
 
struct Result { int x = 1, y = 2, z = 3, w = 4;};
 
Result foo() {
    Result r;
    return std::move(r);  //Кошмар! Здесь компилятор не сможет сделать NRVO!
}
 
Result bar() {
    Result r;
    return r;
}
 
void snafu(int x)
{
    volatile auto a = foo();
    volatile auto b = bar();
}
производит выхлоп:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
foo():
        movabs  rax, 8589934593
        movabs  rdx, 17179869187
        ret
bar():
        movabs  rax, 8589934593
        movabs  rdx, 17179869187
        ret
snafu(int):
        movabs  rax, 8589934593  ; Предварительная загрузка констант
        movabs  rdx, 17179869187
        mov     QWORD PTR [rsp-40], rax   ; Инициализация a.
        mov     QWORD PTR [rsp-32], rdx
        mov     QWORD PTR [rsp-24], rax   ; Инициализация b. Никакой разницы.
        mov     QWORD PTR [rsp-16], rdx
        ret
Как ни удивительно, но даже несмотря на страшный-ужасный std::move переменная a конструируется так же эффективно, как и b, непосредственно в коде вызывающей функции, по тому адресу, по которому и надо было. Именно то, что должна делать NRVO. Никаких потерь производительности не наблюдается, несмотря на крики "всегда! всегда!".

Цитата Сообщение от hoggy Посмотреть сообщение
- а можно просто переменную типа int замувить...
- можно машку за ляжку, козу на возу, не ковыряй в носу!
Хамство ради хамства в чистом виде, ничего информативного. +2 очка.

Цитата Сообщение от hoggy Посмотреть сообщение
у вас там похоже ассм головного мозга.
+1 очко хамства.

Не лучше ль на себя, дружок, оборотиться? Сбавить наглое хамство, повысить внимание к деталям, меньше возводить в абсолют своё кривое понимание стандартов и почаще сверяться с реальностью?

Цитата Сообщение от daun-autist Посмотреть сообщение
Как минимум это обламывается. return statement's expression перестаёт быть object with automatic storage duration (with the same type as the function return type) и начинает возвращать какую-то ссылку.
Вопрос в том, что для компилятора ссылка на локальный объект. Их изначально и замышляли для того, чтобы компилятор мог непосредственно обращаться к объекту, на который ссылаются. Такое происходит в основном во время инлайнинга, когда параметр подставляемой функции становится ссылкой на конкретный локальный объект. Так происходит и при подстановке std::move. И хотя по стандарту компилятор обязан воспроизводить побочные эффекты конструктора перемещения, это не значит, что он не сможет избежать ненужного перекидывания данных.
0
hoggy
6672 / 2856 / 491
Регистрация: 15.11.2014
Сообщений: 6,364
Завершенные тесты: 1
09.07.2017, 11:39 #17
Цитата Сообщение от Nick Alte Посмотреть сообщение
Мне там выше привели пример, где побочные эффекты конструктора становятся видны, потому что обязаны.
нет. не обязаны.

стандарт разрешает компиляторам забить
на все возможные сайд-эффекты конструкторов
в угоду оптимизациям.

в этом и заключается смысл copy elysion как бе.

пример:

http://rextester.com/NIA30417
C++
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
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
 
 
//-------------------------------------------------------------------------        
//---------- кросс-платформенный макрос отображения имени функции ---------
//-------------------------------------------------------------------------        
 
#if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW__)
    #define dFUNCTION __PRETTY_FUNCTION__
#else
    #ifdef _MSC_VER
        #define dFUNCTION __FUNCSIG__
    #else
        #define dFUNCTION __FUNCTION__
    #endif
#endif
 
#define dVIEW_FUNCTION std::cout << dFUNCTION << std::endl;
 
//-------------------------------------------------------------------------         
//-------------------------------------------------------------------------        
//-------------------------------------------------------------------------       
 
struct sample
{
    sample() { dVIEW_FUNCTION; }
    sample(const sample&) { dVIEW_FUNCTION; }
    sample(sample&&) { dVIEW_FUNCTION; }
    const sample& operator=(const sample&) { dVIEW_FUNCTION; }
    const sample& operator=(sample&&) { dVIEW_FUNCTION; }
};
 
sample nrvo()
{
    sample object;
    return object;
}
 
int main()
{
    auto s2 = nrvo(); 
   
    (void)s2;
}
конструктор копии/мув не наблюдаемы.
внезапно?


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

Цитата Сообщение от Nick Alte Посмотреть сообщение
Асм нужен, чтобы понимать, что получается в итоге.
не нужен.
нужно знать и понимать правила языка.
и этого - достаточно.

Цитата Сообщение от Nick Alte Посмотреть сообщение
Иначе можно закончить так, как ты: молясь на смесь стандарта и своих заблуждений и отвергая реальные факты.
если вы без ассма не в состоянии понять,
к чему приводят конструкции на языке с++,
ну значит вы просто балбес.

C++
1
2
3
4
5
6
7
// функция выносит мозг поциэнтам,
// страдающим от болезни "ассм-головного мозга"
template<class ololo) auto trololo()
{
    ololo object;
    return ::std::move(object); 
}
а если наглядные практические примеры кодом,
которые иллюстрируют наличие/отсутствие побочек конструкторов,
не являются для вас "реальными фактами",
значит вы ещё и не адекватный к тому же.

людей, которые противоречат объективной реальности
называют маразматиками.

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

все прочие могут только грубить.
и я вам не грубил.
0
Croessmah
09.07.2017, 16:53
  #18

Не по теме:

Цитата Сообщение от hoggy Посмотреть сообщение
хамить может только нижестоящее лицо вышестоящему
Википедия говорит обратное.

0
dawn artist
Заблокирован
09.07.2017, 19:00 #19
Цитата Сообщение от Nick Alte Посмотреть сообщение
Вопрос в том, что для компилятора ссылка на локальный объект.
Да нет никакого вопроса, написано абсолютно ясно: функция возвращает по значению, а выражение return состоит из имени локального объекта с тем же типом, что и возвращаемое значение у функции. При таких условиях компилятору позволяется не вызывать копирующий или перемещающий конструкторы.

Ни о каких ссылках речи не идёт.
0
hoggy
6672 / 2856 / 491
Регистрация: 15.11.2014
Сообщений: 6,364
Завершенные тесты: 1
09.07.2017, 22:05 #20
Цитата Сообщение от Croessmah Посмотреть сообщение
Википедия говорит обратное.
нет, не говорит.
хотя и искажает.

вероятно она писалась некомпетентным человеком,
который притянул за уши понятие,
в отрыве от его исторического происхождения.

если вам действительно интересно,
то рекомендую вам смотреть в сторону истории происхождения этого понятия,
и толковые словарики аля Ожегова.

в частности,
даже по вашей же ссылке есть пункт касательно России:

В Российской империи дворяне презрительно называли словом «хамство» представителей низших слоёв общества (холоп, лакей)(ц)Викки
вот только викки искажает начальный посыл:
Человек использует тактику хамства в общении с целью явной демонстрации своего превосходства, более высокого социального статуса
(ц)Викки
очевидно, что это не так.
на практике, 99% всех кейсов - банальная грубость,
воспринимаемая "интылэгэнтным" оппонентом:
"он мне нахамииииил!"

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

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

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

для дворянина хам - это холоп, который,
бросил на дворянина косой взгляд,
например.


а в том, что касается реального кейса "демонстрация более высокого статуса",
то для этого случая существует своё отдельное понятие,
называемое "снобизмом".

можете глянуть на викки.
тоже корявенько, но более менее:
https://ru.wikipedia.org/wiki/%D0%A1%D0%BD%D0%BE%D0%B1
0
09.07.2017, 22:05
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.07.2017, 22:05
Привет! Вот еще темы с ответами:

Затираются значения при возврате из функции initializer_list - C++
Дарова. Объясните, почему при возврате объекта инитиализер_лист из функции значения этого листа трутся #include &lt;iostream&gt; using...

std::move() - C++
Есть ли разница между следующими вещами: A = std::move(B); // and std::copy(B.begin(), B.end(), A.begin()); B.clear();

Std::move - C++
Добрый вечер, #include &lt;iostream&gt; using namespace std; class A { private: int x = 10; public: A(int q){ x = q; }

Особенности использования указателей и ссылок в C++ при возврате из функции - C++
Пусть у нас есть некий класс CBase и есть функция, которая создает и возвращает объект класса CBase. Создать она его может стеке или в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru