Оптимизация возвращаемого значения в С++.

Тема в разделе "LANGS.C", создана пользователем Booster, 15 июн 2007.

  1. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    Booster
    в любом случае на компилятор полагаться не стоит. как и на ассемблерные вставки.
    прирост в разы по скорости дает оптимизация самого алгоритма (не путать с оптимизацией кода).
     
  2. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    и все таки, как должен выглядеть конструктор копирования для систем, в которых нет аналога DuplicateHandle?
     
  3. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Nouzui

    Вообще пример был не об этом. Но на твой вопрос отвечу ;) Конструктор копирования для систем, в которых нет аналога DuplicateHandle должен быть приватным :) Как идеал - наследуемся от boost::noncopyable. Это лучше.
     
  4. Bohdan200

    Bohdan200 New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2005
    Сообщения:
    134
    Адрес:
    Lviv
    А не проще писать нормальный код, а не через Ж ??? Программер сам должен заботится о корректности кода, а не возлогать сие на компиляторю.
     
  5. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Bohdan200

    Бугаго)) А можно несколько подробнее? ))))
     
  6. Bohdan200

    Bohdan200 New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2005
    Сообщения:
    134
    Адрес:
    Lviv
    Я об тот этом:
    Код (Text):
    1. File ReadData()
    2. {
    3.     File file;
    4.     ......
    5.     return file;
    6. }
     
  7. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Bohdan200

    Ну? И что тебе тут не нравится? :)
     
  8. Bohdan200

    Bohdan200 New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2005
    Сообщения:
    134
    Адрес:
    Lviv
    Потенциальное место утечки ресурсов созданное сознательно самим прогером. Особенно если не юзать CRT :)
     
  9. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Bohdan200
    IMHO, не стоит оптимизировать код в ущерб понятности и читабельности, если это может сделать компилятор. В этом и состоит призвание ЯВУ.
    ---
    Компилятор позаботится, чтобы не было утечки. Даже если не юзать CRT - это ведь не статический объект.
     
  10. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Bohdan200

    Объявляю тебя гвоздем программы))))) И где же это потенциальное место-то? ))))

    Код (Text):
    1. int main()
    2. {
    3.     return 0; // Потенциальное место для сплоита. А вдруг в вершине стека не адрес возврата, а какая-нибудь х#ня?
    4. }
     
  11. Bohdan200

    Bohdan200 New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2005
    Сообщения:
    134
    Адрес:
    Lviv
    green
    Согласен конечно. Но код выше "узкое место" и от него по-моему проще отказатся и придумать более "надежный" алгос не в ущерб читабильности и прозрачности кода. Может я не прав, это только мое имхо.
     
  12. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Bohdan200

    Ты просто не представляешь на сколько ты не прав и насколько глубокое это имхо))

    edit: орфографейа
     
  13. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    green
    Спасибо за ссылку.
    Если я правильно понял, то Липман прав, и оптимизация должна быть только тогда когда возвращается один объект, а так же как правильно подметил _DEN_ нету конфликта с исключениями. В других случаях полагаться на это не стоит, и надо использовать альтернативу ввиде явных ссылок. А студия видимо пытается дажать оптимизацию и когда возможно возвратить разные объекты, но это уже чисто особенность MS компилятора. Кстати оказывается у MS есть расширение именованных возвращемых значений, которое вроде в стандарт не вошло. Или я заблуждаюсь?
     
  14. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Booster
    Если ф-ция может выбросить исключение, то явные ссылки не решат проблему (точнее они создадут проблему).
    Невозможность NRVO в условиях исключений обусловлена не "тупостью" компилятора, а принципиальной невозможностью обеспечить целостность возвращаемого объекта, если он конструируется in-place, по ссылке. Создание временного объекта на стеке и посл. копирование - единственный реальный выход.

    Насколько я знаю, в Стандарте вообще не говорится об NRVO. Просто компилятору предоставляется свобода заменить инициализацию копированием на "in-place" инициализацию, т.е. опустить лишний копирующий конструктор. NRVO - это следствие такой возможности.

    Вобщем, копирующие конструкторы надо писать так, чтобы алгоритмически программа не зависела от таких оптимизаций.
     
  15. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    green
    Согласен, но вообщем-то исключения исключениям рознь, и в конструкторе этого говна быть не должно, а память под объект выделяется заранее. А значит сконструироваться объект всё же должен. А если пришло исключение например доступа к файлу, что в этом такого страшного, объект то уже сконструирован.
     
  16. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Booster
    Вот смотри (пример кривой, но всё же...):

    Код (Text):
    1. struct Array
    2. {
    3.     Array() : cValidData_(0){}
    4.     int data_[MAX_ARRAY];
    5.     int cValidData_;
    6. };
    7. Array ConstructArray(int v, int c)
    8. {
    9.     Array a;
    10.     for (; a.cValidData_ < c; ++a.cValidData_)
    11.     {
    12.         a.data_[a.cValidData_] = v;
    13.         ThrowingFunc();
    14.     }
    15.     return a;
    16. }
    17. void Test()
    18. {
    19.     Array a;
    20.     try
    21.     {
    22.         a = ConstructArray(0, 10);
    23.     }
    24.     catch(...)
    25.     {
    26.     }
    27.     // работаем с объектом а...
    28. }
    Если ThrowingFunc выбросит исключение, то
    1. результат будет зависеть, от того, применялась ли NRVO.
    2. в случае NRVO работать дальшее мы будем с нецелостным объектом, у которого cValidData_ не соответствует реально заполненному data_.

    Результат неприемлемый по обеим пунктам.
     
  17. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    green
    Пример действительно кривой, ибо нарушает чуть ли не все правила ООП, в частности сокрытие данных и инкапсуляцию.
     
  18. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    green
    Всё равно не понятно.
    Во первых данный код легко изменить, чтобы всегда содержалась коррекная cValidData_. И так и надо сделать, а данный код IMHO по определению не верен, так как исключение прерывает нормальное выполнение кода, и это надо учитывать. И IMHO разница только в том что без ссылки вызовется деструктор. Но и толку то, cValidData_ всё равно не верна, а значит он может отработать не верно. Или что, в случае с автоматическим объектом cValidData_ будет содержать корректное значение? Каким образом? Не понимаю. Или может быть компилятор в этом случае разберётся, и сделает как надо?
     
  19. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Ustus
    Booster
    Cогласен, код кривой, автоматический объект на момент вызова деструктора будет тоже нецелостным.
    Но одно дело вызвать для такого объекта деструктор, а другое - продолжить с ним штатную работу.
    Но даже если переписать так:
    Код (Text):
    1. for (; a.cValidData_ < c;)
    2.     {
    3.         a.data_[a.cValidData_] = v; ++a.cValidData_;
    4.         ThrowingFunc();
    5.     }
    п.1 остается в силе.
     
  20. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    green
    Код кривой не в каком-то конкретном месте, а в принципе. Объект должен обрабатываться как единое целое. Здесь это правило нарушается, что может вызвать сторонние эффекты, и не только пп 1-2.