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

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

  1. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    green
    IMHO по любому косяк. И какая штатная работа когда сработало исключение?
    Разница только в том, что память под объект выделяется снаружи функции, конструктор внутри, деструктор и уничтожение памяти снаружи. Но и здесь пока проблемы не вижу. Так как деструктор в catch тоже должен сработать.
    Пока не вижу проблемы даже при оптимизации компилятором, не говоря уже о явной передачи ссылки.
     
  2. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Ustus
    Боюсь, не понял. Можешь объяснить?

    Booster
    Ну и что? Исключение-то обрабатывается.
    Почему? Объект вне блока try.
     
  3. Booster

    Booster New Member

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

    А почему объект вне try?
    Код (Text):
    1. try
    2. {
    3.   ClassType t = foo();
    4. }
    Код (Text):
    1. try
    2. {
    3.   ClassType t ;
    4.   foo(&t);
    5. }
     
  4. RedLord

    RedLord Member

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

    чего-то не понял ты хочешь сказать, что в коде
    Код (Text):
    1. void Test()
    2. {
    3.     Array a;
    4.     try
    5.     {
    6.         a = ConstructArray(0, 10);
    7.     }
    8.     catch(...)
    9.     {
    10.     }
    11.     // 1111
    12. foo(a);
    13. }
    где 1111 объект а будет разрушен?
     
  5. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Booster
    Дык говорю же - объект вне блока try, поэтому деструктор в catch не сработает. А вообще, конечно, сработает - при выходе из блока, в котором определён объект а, т.е. из ф-ции Test. Таким образом, после catch можно работать с а.
    ---
    Потому, что есть разница между

    Код (Text):
    1. Array a;
    2. try
    3. {
    4.     a = ...
    5. }
    и

    Код (Text):
    1. try
    2. {
    3.    Array a;
    4.    а = ...
    5. }
     
  6. Booster

    Booster New Member

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

    Код (Text):
    1. try
    2. {
    3.   ClassType t = foo();
    4. }
    преобразуется в.
    Код (Text):
    1. try
    2. {
    3.   ClassType t ;
    4.   foo(&t);
    5. }
    Не надо мешать оптимизацию компилятора и явное задание ссылки.

    green
    Да что-то я совсем забыл, что можно ещё и:
    Код (Text):
    1. ClassType t;
    2. try
    3. {
    4.   t = foo();
    5. }
    использовать с оптимизацией компилятора.
    Да согласен, тут возможен большой косяк с оптимизацией.
     
  7. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    green
    Ммм... трудновато будет в двух словах...
    Примерно так: в любом месте, где возможно использование объекта функциями, не относящимися к его реализации - данные объекта должны быть достоверны. Это даже не ООП, это еще в модульном программировании было. Так что надо или доводить операцию до конца, или предусмотреть возможность отката. Простейший пример (правда совсем не из этой области - транзакции в БД). Да, п.1 никуда не делся, но объект останется корректным. И вообще не понимаю, почему этот пункт тебя смущает. Меня больше смущают public-данные - это почти всегда признак плохого стиля.
    Большиство таких проблем оттого, что С++, несмотря на все его ООП все еще остается языком достаточно низкого уровня, чтобы позволять такие штуки. Но тут уже выбирай - или придерживаешься правил, или разгребаешь последствия.
    У меня под боком код лежит - просто пЭсня. Чего стоит например создание массива структур, а потом - использование его через преобразование его адреса к char* и дальнейшей побайтной работы. Причем после вычисления адреса (я не в силах описать этот феерический процесс) он преобразуется опять к указателю на структуру и т.д. Все это щедро разбавлено ассемблерными вставками. У меня много всторостепенных вопросов и два главных: что курил автор сего и где взять такой дури? 8-[ ]
    Сорри за оффтоп, наболело... :)
     
  8. RedLord

    RedLord Member

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

    Код (Text):
    1. struct Array
    2. {
    3. Array() : cValidData_(0){}
    4.     int data_[MAX_ARRAY];
    5.     int cValidData_;
    6. };
    где конструктор вызывающий исключения?

    ConstructArray - вызывает исключения.
     
  9. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Ustus
    А... то есть любая доступная операция с объектом не должна оставлять объект в несогласованном состоянии. Ну да, в принципе согласен.
    Ты только не забывай, что это пример, а не кусок кода из реального проекта. :)
    И разбавлять его не относящимися к делу конструкциями не следует, imho.

    Ну как это - почему? Программа ведь должна быть алгоритмически независима от оптимизаций компилятора.
     
  10. Booster

    Booster New Member

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

    RedLord
    Да согласен, дело не в конструкторе, а в:
    green
    Вообщем всем сенкс, теперь стало ясно.
     
  11. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    green
    Booster
    Логично. Но на практике это не единственный случай, хотя с ходу не решусь назвать примеры. Но конструкторы\деструкторы - это вообще очень тонкая область. Например не стоит закладывать в конструкторы всякие сторонние глобальные эффекты, поскольку не всегда можно предсказать место и количество вызовов конструкторов, простейший пример на форуме уже рассматривали: A a = A(1); - для не особо оптимизирующего компилятора допустимо два вызова конструктора, хотя многие даже с минимальной оптимизацией обходятся одним.
    Но вообще я слабо представляю, где может появится у вменяемого человека такой код, как в примере. Хотя видел и не такое 8-)

    P.S. Кстати, насчет кривости компиляторов - кто может посмотреть GCC поновее? А то в той версии, что мимо меня проходила (не помню точно) некорректно (ИМХО) раскручивается стек при вызове исключения из деструктора - не все деструкторы вызываются.
     
  12. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    Ustus
    а исключения должны покидать деструктор?
     
  13. qwerty_9876

    qwerty_9876 New Member

    Публикаций:
    0
    Регистрация:
    10 апр 2007
    Сообщения:
    47
    TO: RedLord
    >>а исключения должны покидать деструктор?

    Покурите Скотт Мэйерс "Эффективное использование С++", какое издание сейчас последнее не знаю.

    Там про ваш вопрос написано да и про многие другие вопросы.
     
  14. _DEN_

    _DEN_ DEN

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

    Покури 101 правило и рекомендацию от Александреску и Саттера.
     
  15. Booster

    Booster New Member

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

    Ustus
    К сожалению видимо это очень верно. Но всё таки жаль, ведь конструктор по идее очень удобное место для инициализации, а тут приходиться использовать всякие Init для сложных ресурсов. Как то всё это не ООП.
     
  16. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    qwerty_9876
    это был риторический вопрос :)