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

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

  1. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Привет всем.
    В книге Липмана "C++ для начинающих" сказано примерно следующее:
    Он пишет, что предлогалось ввести в стандарт расширение преодолевающее это препятствие, но оно не прижилось. С другой стороны существует оптимизация этого дела, когда вызов функции трансформируется из
    Код (Text):
    1. retClass foo()
    в
    Код (Text):
    1. foo( retClass &obj )
    Что конечно-же гораздо эффективнее. Ещё Липман пишет, что для этого нужно в функции всегда возвращать только один объект (в разных return).
    Смотрю в VC 2003 и вижу, что даже если возвращаются разные экземпляры, то всё равно функция оптимизируется.
    Засим вопрос. Как эта оптимизация регламентируется стандартом, и корректно ли поступает в этом случае VC 2003?
     
  2. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.298
    Адрес:
    Ukraine
    Это как понять?
     
  3. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    IceStudent
    Да я толком сам не совсем понял, привожу цитату дословно.
     
  4. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Кто это такой? Очередной аффтар? :)))

    В 2009-м стандарте будут какие-то move-конструкторы. Возможно они решат проблему. Но не будем забывать, что во-первых, это называется преждевременной оптимизацией, во-вторых, foo( retClass &obj ) не безопасна с точки зрения исключений. Люди, которые на первое место ставят производительность, никогда не научатся программировать.
     
  5. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    _DEN_
    Насколько мне известно этот чел работал со Страструпом. И вообще известный автор и в 3D графике.

    Поподробнее мона?

    Какой толк от программы которая жутко тормозит. С++ и задумывался как язык высокоэффективный, отсюда и его многие проблемы.
     
  6. _DEN_

    _DEN_ DEN

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

    Все понятно)))

    Первый раз слышу.

    1% оверхеда как плата за безопасность и стабильность это более чем приемлемо.

    Мало ли как он там задумывался. С++ это уже давно не Страуструп и не какой-то конкретный человек. С++ сегодня и 10 лет назад - это два совершенно разных языка.


    Код (Text):
    1. int x = 0;
    2. ....
    3. ....
    4. foo(x);
    5.  
    6. void foo(int& x)
    7. {
    8.     x = 10;
    9.  
    10.     throw std::out_of_range();
    11.  
    12.     x = 20;
    13. }
     
  7. _DEN_

    _DEN_ DEN

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

    Код (Text):
    1. void ReadData(File& file)
    2. {
    3.     file.Open();
    4.  
    5.     file.Read();
    6.  
    7.     file.Validate();
    8.  
    9.     throw ...;
    10.  
    11.     file.Close();
    12. }
     
  8. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    не понял? а чем поможет конструктор копирования в ретурне?

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

    _DEN_ DEN

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

    Код (Text):
    1. File ReadData()
    2. {
    3.     File file;
    4.  
    5.     file.Open();
    6.  
    7.     file.Read();
    8.  
    9.     file.Validate();
    10.  
    11.     throw ...;
    12.  
    13.     file.Close();
    14.  
    15.     return file;
    16. }
    На эту тему я даже спорить не буду. Вообще не буду.
     
  10. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    _DEN_
    Не дошло и сейчас.
    Кто мешает перехватить все исключения в блоке, затем в его обработчике сделать необходимую очистку, и снова инициировать исключение.
    Но всё же это не совсем в тему. Спорить о том надо ли передавать значение или ссылку, не совсем корректен. Есть случаи когда издержки 1% процент, а есть когда 100%. Вопрос в том как это регламентирует стандарт, и чего нужно от этого ожидать. Хотя если есть какие-то проблемы (опять таки например исключения), то тогда хотелось бы как-нибудь управлять процессом оптимизации.

    Да и всё же, объясни популярно в чём трабла с исключениями?
     
  11. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    _DEN_
    деструктор (если я тебя правильно понял) должен по-хорошему выполнять действия, обратные конструктору. рассчитывать на полную очитку после всех действий только в деструкторе, без явного вызова методов, неправильно само по себе. хотя иногда себя оправдывает. по крайней мере, я так считаю
     
  12. _DEN_

    _DEN_ DEN

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

    Все понятно. Ты просто не знаешь что такое "код безопасный с точки зрения исключений".

    После вышеуказанной цитаты это не реально)).

    Nouzui

    Поздравляю тебя. Ты считаешь неправильно.
     
  13. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    _DEN_
    нну ладно..

    давай рассмотрим конкретно.. итак, твой File - класс, оборачивающий работу с файлами. Возьмем для начала windows и апи. поехали..

    class File
    {
    HANDLE hFile;
    ....
    };

    File::File(): hFile(INVALID_HANDLE_VALUE) {};

    какой-то тип File::Open(...)
    {
    #if DEBUG
    if(hFile!=INVALID_HANDLE_VALUE)
    ....
    #endif
    hFile= CreateFile(...);
    if(hFile==INVALID_HANDLE_VALUE)
    кстати, что должно быть здесь, на твой взгляд?
    ...
    }

    Read и Validate сам напишешь. кстати, что такое Validate?

    void, наверное File::Close(...)
    {
    #if DEBUG
    if(hFile==INVALID_HANDLE_VALUE)
    ...
    #endif
    CloseHandle(hFile);
    hFile= INVALID_HANDLE_VALUE;
    }

    File::~File()
    {
    if(hFile!=INVALID_HANDLE_VALUE)
    Close();
    }

    так все?
     
  14. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    _DEN_
    Признаюсь не знаю, но догадываюсь. Конечно в варианте со ссылкой освобождение ресурсов автоматически не произойдёт, и это безусловно плохо. Но всё же правильно разрулить эту ситуацию имхо возможно. Так как дефолтовый конструктор генерировать исключения не должен, и память под объект выделяется заранее, то у этого объекта можно самим вызвать деструктор, хотя безусловно всё это не очень здорово, но имхо работоспособно, тем более что не всегда исключения нужны.
     
  15. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    Booster
    судя по всему вопрос не об оптимизации кода программером (с учетом или без влияния на него исключений), а об оптимизации кода на этапе компилирования.
    ISO C++ раздел 12.8 пункт 15
    похоже VC прав.
     
  16. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    RedLord
    Совершенно верно. Хорошо что это стандартизировано. Но по поводу:
    Все же не понятно. Если мы возвращаем один объект, тогда мы вызываем конструктор по ссылке, делаем с ним чо-то и в конце спокойно забываем о нём. Но если у нас произошла промашка и у нас возвращается в итоге другой объект, конструктор копирования всё равно должен вызваться. Вся оптимизация есно на смарку. Получается что когда-то возможна оптимизация, а когда-то и нет, а это IMHO не хорошо. По идее это жёстко должно быть прописано, иначе возможно непредвиденное поведение.
     
  17. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    Booster
    подробнее можно. я не совсем вкурил
    а лучше пример такого кода набросай
     
  18. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    RedLord

    Ну вот такое
    Код (Text):
    1.   RetClass foo()
    2.   {
    3.     RetClass obj;
    4.     ret obj;
    5.   }
    6.   RetClass obj = foo();
    превращается компилятором в
    Код (Text):
    1.  
    2.   foo(&obj)
    3.   {
    4.      obj.constructor();
    5.   }
    6.   выделяется неинициализированная память под RetClass obj.
    7.   foo(&obj);
    Внутри foo срабатывает конструктор для obj.
    Но если мы возвращаем в разных случаях разные объекты, то получаеся облом, а студия всё равно оптимайзит. И не ясно как тут нужно оптимайзить, и как тут стандарт регламентирует, то есть когда у нас есть в функции несколько return c разными объектами. Получается то оптимизация сработает, а то нет, не ясность.
     
  19. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    Booster

    насколько я понял ты говоришь о такой варианте кода
    Код (Text):
    1. struct A
    2. {
    3. A(int x);
    4. };
    5.  
    6. A foo(bool flag)
    7. {
    8. if (flag)
    9. {
    10. return A(1);
    11. }
    12. return A(5);
    13. }
    я не знаю, как разрабы компилеров реализуют указанный пункт Стандарта, но никаких проблем, с точки зрения компилера, для оптимизации кода я не вижу.
    в любом случае - экспериментируй.
    разрабы компилеров не всегда блюдят Стандарт.
     
  20. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.218
    Адрес:
    Ukraine