Здравствуйте, WolfHound, Вы писали:
WH>Ты всетки объясни мне какая разница между ЯВНЫМ обходом тапизации и unsafe.
разница в том, что все блоки unsafe находятся с помощью простого текстовго поиска по файлам проекта. При желании эту возможность можно вобще запретить.
Мне чертовски интересно узнать, как ты будешь контролировать нарушения типизации в проекте, над которым работают десятки людей.
WH>Так ведь и в С++ нормальные люди без хаков живут. А те хаки которые есть скрыты под мощьной защитой.
мощная защита? Расскажи плиз, я просто умираю от любопытства.
WH>Последствия конечно будут не столь разрушительны как на С++ но легче от этого не становится.
Как это не становится?
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[20]: Частота ошибок в зависимости от языка: что делать?
Здравствуйте, Дарней, Вы писали:
Д>разница в том, что все блоки unsafe находятся с помощью простого текстовго поиска по файлам проекта. При желании эту возможность можно вобще запретить. Д>Мне чертовски интересно узнать, как ты будешь контролировать нарушения типизации в проекте, над которым работают десятки людей.
codereview в любом случае нужен.
WH>>Так ведь и в С++ нормальные люди без хаков живут. А те хаки которые есть скрыты под мощьной защитой. Д>мощная защита? Расскажи плиз, я просто умираю от любопытства.
Ну попробуй взломать STL'ный контейнер без явных хаков.
WH>>Последствия конечно будут не столь разрушительны как на С++ но легче от этого не становится. Д>Как это не становится?
Да вот так. Пользователю без разници свалилось приложение по AV или по NullReferenceException захватив с собой все что сделал пользователь.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>А что такого крутого в дельфийском RTTI? Возможность перебрать свойства в published секции? WH>Вот только толку от этого мало.
Ну не знаю. Как справедливо заметил Влад рядом, комоненты без этого нереализуемы. А сколько раз я маялся с сериализацией структуры, каждое поле ручками сохрани-восстанови, да не забудь синхронизироваться, если новые поля появились? Это ж засношаться просто.
(hint: я, наверное, употребил в прошлый раз термин RTTI немного не в общепринятом смысле, включая в него и reflection).
WH>Хотя скорее всего она не доживет ибо ее убъет .НЕТ
Я думаю так и будет. Но мы же о прошлом, не о будущем, правда? Сегодня у Дельфи уже нет преимуществ перед C#... что и закономерно, учитывая, что у них один создатель, правда?
T>>Второй раз слышу этот тезис. Кто-нибудь мне расскажет о том, в чём концептуальной отличие фабрики от конструктора?! Вроде б и та и тот задачей ставят создание целостного объекта (банду четырёх я читал, не помогло). WH>Ты вобще понимаешь механику работы конструкторов/деструкторов в С++?
Прекрасно понимаю. Только "конструктор в C++" и "конструктор вообще" суть разные вещи. Задача конструктора — сконструировать экземпляр класса, "по-моему так" (c) Винни-Пух. Если не прав — поправляйте (ссылка на источник строго приветствуется, но и без неё покатит). И конструктор C++ и конструктор Дельфи и "фабричный метод" конструируют экземпляр класса. В общем случае, я бы выделил в этом процессе две стадии:
1. Инициализация. Это примерно то, чем занимаются конструкторы C++. Вызываются инициализаторы всех родительских классов: от самого общего к самому точному. Инициализатору доступны методы только его класса и родительских, вызовы виртуальных методов не ведут к вызову метода потомка. Задача — как-то проинициализировать все поля (не обязательно в целостное состояние). Идея та, что код инициализатора простейший, его задача только забить поля и выполнить простые контроли параметров.
2. Собственно, конструирование. Это то, что в C++ предлагается выносить в особые фабрики. Произвольный код для окончательного построения класса. Виртуальные функции работают правильно — вызывая самого нижнего потомка, где они переопределены.
Достоинство дельфийских конструкторов в том, что они совмещают обе этих стадии, а беда — что не разделяют их чётко.
Любителям обызывать конструкторы Дельфи недофабриками напомню, что есть масса народа, которая конструкторы C++ обызвает инициализаторами и сокрушается "а вот если бы там были настоящие конструкторы..."
WH>Смотри boost::format
Гляну. Но я прямо сейчас могу сказать, что там рожается >=4 временных объектов, которые постепенно накапливают все необходимые форматные параметры. Лишнее копирование, лишние классы. Нет, оно работает, верю, только решение с одной функцией, получающей форматную строку и массив параметров куда проще и понятней. Я ж говорю, что C++ это мощный экспериментальный полигон, где забабахать почти любую вещь можно.
WH>Угу. Вот только на дельфевем RTTI далеко не уедешь, фабрики нужны гораздо реже чем полноценные конструкторы к томуже фабрику легко написать, а вот сэмулировать конструктор на дельфе
Расшифруйте термин "полноценный конструктор", pls. Пока мне Дельфийские конструкторы кажутся более полноценными (хоть и более опасными).
WH>переменное число параметров нафиг не упало см выше.
Переменное число параметров в общем-то не нужно (его в Дельфе и нет, кстати), а вот легко задать контейнер надо бы. Ну-ка — как передать в функцию ссылку на массив произвольной размерности, создав массив прямо при вызове функции?
В Дельфи просто: getMax( [a, b, c, d] ). В C++ нужна вторая строчка:
type tmp[] = (a, b, c, d);
getMax( tmp, tmp + sizeofa(tmp) ); // следуя стилю STL с итератором начала и конца; sizeofa(x) = sizeof x/sizeof x[0]
WH>ИТОГО: Отсутствие необходимых инструментов компенсируется парой сомнительных фичек
Необходимых для каких задач? Для написания драйвера, клиентской части работы с БД, текстового, да и графического редактора все необходимые фичи имеются. А сомнительность фичек я буду обсуждать со знатоками вкуса устриц, сорри.
--
wbr, Peter Taran
Re[21]: Частота ошибок в зависимости от языка: что делать?
Здравствуйте, WolfHound, Вы писали:
WH>codereview в любом случае нужен.
вопрос только — насколько нужен. Обнаружить, кому давать по балде за несанкционированное применение unsafe, можно почти без усилий
А искать нарушение правил приведения типов ты как будешь? Просматривать код файл за файлом?
WH>Ну попробуй взломать STL'ный контейнер без явных хаков.
что значит — "взломать"? Поконкретнее, пожалуйста.
WH>Да вот так. Пользователю без разници свалилось приложение по AV или по NullReferenceException захватив с собой все что сделал пользователь.
Ну во первых — NullReferenceException говорит только о логической ошибке, и в большинстве случаев он не мешает продолжать работу проги. Как минимум — освободить все взятые ресурсы. Если произойдет AV, никакая работа приложения уже невозможна.
Во вторых — рассмотрим программирование серверов приложений. Одно дело, когда один клиент получил сообщение об ошибке. Другое дело — когда сервер с треском упал и все сеансы работы умерли. Есть все-таки разница, не правда ли?
Дарней wrote:
> WH>Да вот так. Пользователю без разници свалилось приложение по AV или > по NullReferenceException захватив с собой все что сделал пользователь. > Ну во первых — NullReferenceException говорит только о логической > ошибке, и в большинстве случаев он не мешает продолжать работу проги. > Как минимум — освободить все взятые ресурсы. Если произойдет AV, > никакая работа приложения уже невозможна.
С использованием SEH — вполне возможна, лично такое писал.
Здравствуйте, Cyberax, Вы писали:
C>С использованием SEH — вполне возможна, лично такое писал.
Я в курсе, что возможна.
Только имеет ли смысл работа с данными, которые (вероятно) повреждены проходом по памяти?
Максимум, что здесь можно сделать — выдать сообщение о критической ошибке и сделать дамп памяти, после чего помахать пользователю ручкой и пожелать больше удачи в дальнейшей работе.
Если в обработчике SEH делаются любые операции с бизнес-данными — то за такие фокусы разработчика надо кастрировать и повесить на входной двери офиса, чтобы не распространял свой генофонд.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[24]: Частота ошибок в зависимости от языка: что делать?
Дарней wrote:
> C>С использованием SEH — вполне возможна, лично такое писал. > Я в курсе, что возможна. > Только имеет ли смысл работа с данными, которые (вероятно) повреждены > проходом по памяти?
Физически разделять данные на разные домены, находящиеся в разных
приватных кучах. Так по жизни делают unmanaged сервера приложений типа
MTS или реализаций CORBA.
> Если в обработчике SEH делаются любые операции с бизнес-данными — то > за такие фокусы разработчика надо кастрировать и повесить на входной > двери офиса, чтобы не распространял свой генофонд.
В обработчике SEH можно поставить сохранение данных и попытку
самовосстановления. Естественно, надо сделать так, чтобы не испортились
существующие записи.
Здравствуйте, Cyberax, Вы писали:
C>Можно, хотя и немного сложнее.
Так это почти то же, что и передать ссылки на переменные параметрами operator(). Энто ж самое главное западло — что их все перечислять надо тем или иным способом и никуда не сбежишь от этого. А перечислять-то и не хочется.
C>С небольшой долей фантазии можно сделать и closure'ы.
tarkil wrote:
> C>Можно, хотя и немного сложнее. > Так это почти то же, что и передать ссылки на переменные параметрами > operator(). Энто ж самое главное западло — что их все перечислять надо > тем или иным способом и никуда не сбежишь от этого. А перечислять-то и > не хочется.
Разница в том, что тут надо всего один раз инициализировать структуру, и
потом сколько угодно ей пользоваться в методе.
Хотя такие трюки бывают нужны относительно редко, так что особых проблем
нет.
> C>С небольшой долей фантазии можно сделать и closure'ы. > Как-как ты сматерился?
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, tarkil, Вы писали:
T>>4) Аккуратное программирование. В конце-концов, создавать объект приписывая к нему try-finally и писать в деструкторе уничтожение всего вложенного не так уж трудно — я быстро привык Однако, 1 или 2 поприятнее, да. WH>Весьма хреновый выход ибо если надо создать несколько объектов причем конструктор каждого из них может кинуть искольчение... WH>disclaimer: на дельфе не писал очень давно. WH>
WH>begin
WH> obj1 := SomeClass.Create;
WH> try
WH> begin
WH> obj2 := SomeClass.Create;
WH> try
WH> begin
WH> obj3 := SomeClass.Create;
WH> try
WH> begin
WH>...
WH> end
WH> finally
WH> begin
WH> obj3.Free();
WH> end
WH> end
WH> finally
WH> begin
WH> obj2.Free();
WH> end
WH> end
WH> finally
WH> begin
WH> obj1.Free();
WH> end
WH>end;
WH>
А теперь то же самое руками квалифицированного девелопера:
Здравствуйте, Sinclair, Вы писали:
S>Здесь мы пользуемся тем, что вызов Free на nil безопасен. Поэтому в какой бы момент ни было брошено исключение, finally отработает корректно.
В любом случае на С++ короче и безопеснее ибо контролирует компилятор.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: Частота ошибок в зависимости от языка: что делать?
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, VladD2, Вы писали:
VD>>Кстати, было бы куда лучше если бы можно было создавать наследников вэлью-типов.
Д>Будут проблемы со срезкой.
С чего бы?
Единственный, как бы, недостаток состоит в том, что переменная на 4 байта больше (чтобы хранить тэг типа).
Здравствуйте, WolfHound, Вы писали:
WH>Толку то от этой дельфи... какой смысл ее использовать? В лучшем случае ее ожидает судьба J#'а.
Цитирую:
1)ГЦ. В дельфе нет.
Надо объяснять насколько ты заблуждаешся?
VD>>Это есть везде. Вот только в С++ чувствуется острее всего. WH>Я знаю ты мне не веришь но у меня их нет. Что я делаю не так?
Все у тебя есть. Ты сам говоришь насколько быстрее программировать на Шарпе. Так вот отсуствие траха с "этим" — это очень некислая часть того самого ускорения.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[21]: Частота ошибок в зависимости от языка: что делать?
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, VladD2, Вы писали:
WH>>>Тут ты тоже явно обошол защиту. Так что... VD>>Какую? WH>Дурака выключи.
Что за мовитон Шура? Я вас умоляю...
И все же какая такая защита у нас появилась в плюсах?
WH>1)Контейнеры уже давно написаны.
Все? Как бежит время...
WH>2)Контейнеры должны писать опытные люди. Если опыта не хватает то надо использовать STL.
И СТЛ должны использовать опытные люди. Да и опытным людям нужны разные костыли вроде баунд-чекеров. И все по причине зелания жить на грани крутизны. Не, спасибо, я пешком постаю.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[25]: Частота ошибок в зависимости от языка: что делать?
Здравствуйте, Cyberax, Вы писали:
C>Физически разделять данные на разные домены, находящиеся в разных C>приватных кучах. Так по жизни делают unmanaged сервера приложений типа C>MTS или реализаций CORBA.
от прохода по памяти это все равно не спасет
C>В обработчике SEH можно поставить сохранение данных и попытку C>самовосстановления. Естественно, надо сделать так, чтобы не испортились C>существующие записи.
А как ты определишь. какие данные повреждены а какие нет?
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[17]: Частота ошибок в зависимости от языка: что делать?
Здравствуйте, VladD2, Вы писали:
VD>Очень верно, что слова "почти безопасные" ты взял в ковычки. Потому как это тоже самое что "чуть-чуть беременная". Нет никаких проблем натварить любого бреда и со static_cast-ами: VD>
VD>for (int i = 0; i < 10; i++)
VD> static_cast<A*>(static_cast<void*>(&i))->~A();
VD>
VD>Этот код скопилируется без броблем. А по стути он аналогичен предыдущему.
Да, хак статик-каста через void известен, как и то, что это именно хак. Любые compile-time приведения через void* потенциально опасны ввиду нарушения адресной арифметики.
Мне напомнить про то, что я могу в unsafe режиме в донете и не такое сделать непосредственно в рамках C#?
Почему мы все время говорим о том, что "а вот у здесь можно вот такую-то лажу нагнать", вместо того, чтобы обсудить, где удобнее не нагнать эту лажу. В дотнете в interop вообще все можно уронить с пол-пинка, однако же пользуемся.
Я вообще не вижу причин огорчаться в случае, если некорректная программа падает, дык — это корректное поведение неккоректной программы. Меня больше интересует возможность в рамках некоего инструмента писать так, чтобы уменьшить вероятность собственных ошибок.
Знаю, что ты давно пересел на 2.0, но у нас коммерческие проекты, и они, разумеется, на 1.1. И сильной статической типизации плюсов порой ой как не хватает.
Для того, чтобы избежать "обезличенных" сигнатур, типа
Method1(int, int);
Method2(object, object);
мы извращаемся как можем, и, на мой взгляд, не всегда корректно применяем имеющиеся штатные ср-ва. Однако, они себя окупают.
Например.
public enum ObjectIdT { eNoObject };
— пустой енум, мы его используем как типизированный int, используя весь диапазон int-значений. Это немного неккоректно, зато помогло найти несколько ошибок, при добавлении типизации в метод:
Method1(ObjectIdT, int);
C object — та же кухня, только еще хуже. Вводим пустые интерфейсы-таги, типа:
public interface I1 {};
чтобы написать затем типа такого:
Method2(I1, object);
Да, "шаблонность" нам малость поможет потом частично разрулить эти безобразия, однако, прежнего удобства от наличия сильной статической модели кода, какую привык наблюдать в С++, все-равно не получим даже в 2.0. (У меня Express, все ограничения дженериков уже просек).