Booster в любом случае на компилятор полагаться не стоит. как и на ассемблерные вставки. прирост в разы по скорости дает оптимизация самого алгоритма (не путать с оптимизацией кода).
и все таки, как должен выглядеть конструктор копирования для систем, в которых нет аналога DuplicateHandle?
Nouzui Вообще пример был не об этом. Но на твой вопрос отвечу Конструктор копирования для систем, в которых нет аналога DuplicateHandle должен быть приватным Как идеал - наследуемся от boost::noncopyable. Это лучше.
А не проще писать нормальный код, а не через Ж ??? Программер сам должен заботится о корректности кода, а не возлогать сие на компиляторю.
Bohdan200 IMHO, не стоит оптимизировать код в ущерб понятности и читабельности, если это может сделать компилятор. В этом и состоит призвание ЯВУ. --- Компилятор позаботится, чтобы не было утечки. Даже если не юзать CRT - это ведь не статический объект.
Bohdan200 Объявляю тебя гвоздем программы))))) И где же это потенциальное место-то? )))) Код (Text): int main() { return 0; // Потенциальное место для сплоита. А вдруг в вершине стека не адрес возврата, а какая-нибудь х#ня? }
green Согласен конечно. Но код выше "узкое место" и от него по-моему проще отказатся и придумать более "надежный" алгос не в ущерб читабильности и прозрачности кода. Может я не прав, это только мое имхо.
Bohdan200 Ты просто не представляешь на сколько ты не прав и насколько глубокое это имхо)) edit: орфографейа
green Спасибо за ссылку. Если я правильно понял, то Липман прав, и оптимизация должна быть только тогда когда возвращается один объект, а так же как правильно подметил _DEN_ нету конфликта с исключениями. В других случаях полагаться на это не стоит, и надо использовать альтернативу ввиде явных ссылок. А студия видимо пытается дажать оптимизацию и когда возможно возвратить разные объекты, но это уже чисто особенность MS компилятора. Кстати оказывается у MS есть расширение именованных возвращемых значений, которое вроде в стандарт не вошло. Или я заблуждаюсь?
Booster Если ф-ция может выбросить исключение, то явные ссылки не решат проблему (точнее они создадут проблему). Невозможность NRVO в условиях исключений обусловлена не "тупостью" компилятора, а принципиальной невозможностью обеспечить целостность возвращаемого объекта, если он конструируется in-place, по ссылке. Создание временного объекта на стеке и посл. копирование - единственный реальный выход. Насколько я знаю, в Стандарте вообще не говорится об NRVO. Просто компилятору предоставляется свобода заменить инициализацию копированием на "in-place" инициализацию, т.е. опустить лишний копирующий конструктор. NRVO - это следствие такой возможности. Вобщем, копирующие конструкторы надо писать так, чтобы алгоритмически программа не зависела от таких оптимизаций.
green Согласен, но вообщем-то исключения исключениям рознь, и в конструкторе этого говна быть не должно, а память под объект выделяется заранее. А значит сконструироваться объект всё же должен. А если пришло исключение например доступа к файлу, что в этом такого страшного, объект то уже сконструирован.
Booster Вот смотри (пример кривой, но всё же...): Код (Text): struct Array { Array() : cValidData_(0){} int data_[MAX_ARRAY]; int cValidData_; }; Array ConstructArray(int v, int c) { Array a; for (; a.cValidData_ < c; ++a.cValidData_) { a.data_[a.cValidData_] = v; ThrowingFunc(); } return a; } void Test() { Array a; try { a = ConstructArray(0, 10); } catch(...) { } // работаем с объектом а... } Если ThrowingFunc выбросит исключение, то 1. результат будет зависеть, от того, применялась ли NRVO. 2. в случае NRVO работать дальшее мы будем с нецелостным объектом, у которого cValidData_ не соответствует реально заполненному data_. Результат неприемлемый по обеим пунктам.
green Пример действительно кривой, ибо нарушает чуть ли не все правила ООП, в частности сокрытие данных и инкапсуляцию.
green Всё равно не понятно. Во первых данный код легко изменить, чтобы всегда содержалась коррекная cValidData_. И так и надо сделать, а данный код IMHO по определению не верен, так как исключение прерывает нормальное выполнение кода, и это надо учитывать. И IMHO разница только в том что без ссылки вызовется деструктор. Но и толку то, cValidData_ всё равно не верна, а значит он может отработать не верно. Или что, в случае с автоматическим объектом cValidData_ будет содержать корректное значение? Каким образом? Не понимаю. Или может быть компилятор в этом случае разберётся, и сделает как надо?
Ustus Booster Cогласен, код кривой, автоматический объект на момент вызова деструктора будет тоже нецелостным. Но одно дело вызвать для такого объекта деструктор, а другое - продолжить с ним штатную работу. Но даже если переписать так: Код (Text): for (; a.cValidData_ < c;) { a.data_[a.cValidData_] = v; ++a.cValidData_; ThrowingFunc(); } п.1 остается в силе.
green Код кривой не в каком-то конкретном месте, а в принципе. Объект должен обрабатываться как единое целое. Здесь это правило нарушается, что может вызвать сторонние эффекты, и не только пп 1-2.