Здравствуйте, Banned by IT, Вы писали:
I>>А если учесть, что на менеджед пишется примерно 99% всех проектов, то это да, большой прикол. BBI>Ага, но при этом 90% софта native. Вот ведь парадокс.
Кто тебе такое сказал ?
BBI>Это ж ведь только с твоей колокольни такой вид открывается.
Нативный софт начали писать еще в 80х и с каждым годом в общей массе его становится меньше и меньше.
Так что, извини, я тебя невольно запутал.
ГВ>>Это как раз очень простая ситуация. Врубись: я держу ссылку на объект, предполагая, что он кому-то нужен. Но этот кто-то этот самый объект сейчас "выкидывает". В unmanaged произойдёт "ой" из-за внезапного delete, а в managed — будет тишина и я буду продолжать работать с никому не нужным объектом. S>А можно поподробнее мне объяснить, за счёт чего произойдёт этот "ой"? S>Вот я обращаюсь int a = p->m_InstanceCount. Понятное дело, что никаких AV я не дождусь — AV работают только если я далеко промахнулся мимо памяти программы. А тут всё по прежнему в пределах хипа, всё в порядке.
Да, правильно. AV в данном случае, скорее всего не будет, хотя это совсем не обязательно: если ты читаешь не целое число, а какой-нибудь указатель по указателю, то можешь налететь и на AV. В общем, куча загадочных эффектов таки случится.
S>Прочитал я себе целую переменную и пошёл хреначить дальше. Продолжу работать с чем-то другим — 0xDEADBEEF если повезло, или, скажем, с 0, если не повезло и в это место распределился совершенно другой объект. Всё выглядит нормально, только глючит неестественным образом.
DEADBEEF — это, считай, удача.
S>Или, ещё лучше, я пишу p->m_InstanceCount--. Кто ж его знает, что я там такое декрементировал? S>За счёт какой магии я получу "ой", и в чём он выразится?
Никакой магии. Банальная ошибка, которыми вы тут всех пугали, со всеми её прелестями и непредсказуемостями. Разница только в том, что managed такую ошибку не продиагностирует вообще никак, а unmanaged — хоть как-то.
Похоже, что у нас с тобой просто разное отношение к таким ошибкам: я к ним отношусь без излишнего паникёрства. Понятно, что в качестве нормы такой подход к диагностике ошибок использовать нельзя, но если уж ошибка допущена, то...
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Banned by IT, Вы писали:
I>>Может и ничего не стоит. А кто её умеет и где посмотреть продукты, где бы эта безопасность что ничего ен стоит была использована ? Я чет как ни залезу в чей нибудь С++ код, так вечно хаос с указателями. Такое ощущение что RAII еще не изобрели или изобрели но не рассказали, как правильно им пользоваться
BBI>Ну извини. То, что тебя окружают индусокодеры означает совсем не это.
Здравствуйте, Banned by IT, Вы писали:
I>>По трудоёмкости может и не стояли рядом, но глядя на обилие ошибок с указателями в сиплюсных программах, как то возникает сомнение что люди в общей массе вообще способны освоить эти указатели BBI>Встречал людей которые в принципе не могли понять как работает указатель и как им пользоваться. Т.е. в принципе не понимали. Как работает индекс по массиву — понятно, а как работает BYTE* по flat оперативке — полный ступор и пустота в глазах.
Вот вот. А между тем они работают в тч. сиплюсниками на самых разных конторах и можешь быть спокоен — я тут абсолютно ни при чём. Собственно судя по отзывам людей с твоей конторы про с++ на лялихе ...
Здравствуйте, vdimas, Вы писали:
I>>Прикол в том, что средний программист уже не способен писать на С++. Вот это действительно прикол. А если учесть, что на менеджед пишется примерно 99% всех проектов, то это да, большой прикол.
V>Мде? А я вижу, что практически все популярные программы на нейтив, даже которые опенсорсные.
и много этих популярных программ ?
>Допускаю, что окружающие тебя 99% коллег пишут на дотнете, это лишь значит, что у тебя такая выборка.
Неправильное допущение и выводы следовательно неправильные.
>Попробуй на досуге набрать в гугле "новости софта", или зайти на любой пиратский торрент и посмотреть в топах, что народ качает. Дотнет там оч редко, только в утилитах каких-нить, администраторских.
Расклад по тому, что нынче пишется в каких объемах можно сделать тупо по количеству вакансий. Как то я не вижу значительного кол.ва вакансий на с++ и не вижу, что бы ЗП в с++ отражали спрос на с++
Здравствуйте, vdimas, Вы писали:
V>Кроме того, любой биндинг выполняет последовательно все probe на наличие той или иной технологии/соглашений для биндинга и выбирает первый подходящий вариант (см рефлектром). По моим замерам, это в среднем вдвое тормозило в сравнении с WinForms, бо там вариантов меньше рассматривается, и все эти варианты работают на рефлексии.
В моем примере сплошные шаблоны контролов, поэтому там нет Рефлексии. Привязка свойств двух DependencyObject работает без нее.
V>Ну и помимо прочего, не забываем про большее кол-во библиотек и типов, в т.ч. специализированных генериками, например, чуть ли не каждый экземпляр DependencyProperty — это новый тип, который требует инициализации. А вот иницализация типов — очень затратное дело. Ну и затем инициализация статиков практически в каждом типе WPF, а вызов каждого статического конструктора сопровождается глобальной блокировкой и ожиданием из других потоков (межпотоковые сигналы во всей красе). В общем, много чего набегает.
Не понимаю, почему каждый DependencyProperty — это новый тип? Тип всегда один — DependencyProperty. Затраты на DependencyProperty.RegisterCommon вышли еще меньше, чем сборка мусора. И потом, я все объекты создаю до того, как WPF вступает в действие, поэтому инициализация статики — ничтожная вещь. Тяжелым получилось воплощение XAML в контролах, но ведь и контролов у меня свыше 5000(!). Если уменьшить до 75 скажем, то затраты по WPF составляют лишь 25% времени. В-общем, я пришел к выводу, что долгий старт не столько из-за WPF, сколько из-за .Net в принципе. Студия 2010-я, кстати, тоже тому пример. Первый запуск долгий, повторный — почти что пшик. И это мой рабочий комп всего с 2 Гб оперативы
Здравствуйте, gandjustas, Вы писали:
ГВ>>Это как раз очень простая ситуация. Врубись: я держу ссылку на объект, предполагая, что он кому-то нужен. Но этот кто-то этот самый объект сейчас "выкидывает". В unmanaged произойдёт "ой" из-за внезапного delete, а в managed — будет тишина и я буду продолжать работать с никому не нужным объектом.
G>Да, и managed программа будет работать и работать корректно.
Разницу между "корректно" и "без выбрасывания исключений" надо объяснять?
G>В unmanaged в лучшем случае упадет. Разницу понимаешь?
Естественно, понимаю.
[...]
G>Тут получается что просто не договорились между managed и unmanaged о tread safety.
Вот, живой пример вреда code samples: собеседник начинает делать далеко идущие выводы из ничего. Код сугубо иллюстративный и показывает только то место, где возникала потеря объекта данных. В реальности и сам код был сложней, и ещё довольно сложная логика перезапуска потоков, из-за которой, в общем, всё и случилось. Но к тому, на что я хотел обратить внимание, это не относится. А про однопоточность unmanaged всем и так было известно.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, samius, Вы писали:
V>>Вообще, для случая inline-исполнения оба варианта эквивалентны, и там и там протягивается константа времени компиляции. Ты, случайно, не определял тела методов за пределами класса без inline? S>Случайно тела методов были в теле класса. Те методы однострочные, жалко было места для дублирования сигнатуры. Но раз я обнаружил разницу в размере бинарников, то очевидно что варианты не эквивалентны. Тем более, что класс во втором случае имеет поле, в котором хранит переданный в конструкторе char.
Ну и что, если объект временный на стеке, его класс инлайный, происходит инициализация значением времени компиляции — это одно и то же в итоге. В общем, надо посмотреть на код, тогда я мог бы не гадать на кофейной куче... Может у тебя подчиненные парсеры хранятся как мемберы более высокоуровневых. Тоды ой.
V>>Есть еще версия, что уровень максимальной вложенности, рассматриваемый компилятором, ограничен (оно так и есть, иначе бы программа компиллировалась бесконечно, бо слишком много комбинаций получалось бы на самом верхнем уровне). Но мы не знаем ни уровня такой вложенности компилятора (для GCC недавно было 8 вроде), ни получаемого у тебя уровня вложенности на верхнем уровне. S>комбинаций немало (http://www.w3.org/TR/CSS2/grammar.html#scanner, http://www.w3.org/TR/CSS2/grammar.html#grammar)
Большой вложенности цепочек не вижу, однако.
V>>Возможно, стоило вывести несколько "промежуточных" достаточно высокоуровневых фиксированных типов парсеров (параметризируемых обычными аргументами, а не шаблонными), именно на них уменьшив общее комбинаторное число, а не на самых низкоуровневых. Смотреть надо и пробовать. S>Я так и сделал. Параметризовал тип парсера лишь типом его результата, и убрал типы парсеров-участников комбинации.
Я про то, что низкоуровневые моли идти через кодогенерацию, а высокоуровневые — работать по данным, то бишь некоторые парсеры, назовем их среднего уровня, должны предоставлять унифицированный интерфейс, и более высокоуровневые парсеры строятся как интерпретатор на их основе. Все равно быстродействие критично на самом низком уровне только.
V>>А я просто пользуюсь тем, что декомпозиция в С++ практически бесплатна, в отличие от. Оч удобно декомпозировать на совсем маленькие типы с некоторым заведомо безопасным интерфейсом, с проверкой всех контрактов и прочим, затем построить глобальные операции вокруг таких типов (тоже оч удобно в отличие от ). В таком подходе высокоуровневые объекты "по месту" собираются уже из отлаженных запчастей такой инфраструктуры, которая получается высокоуровневой сама по себе, потому что в прикладном коде мы уже оперируем прикладными сущностями из инфраструктуры. S>Если я все верно понял, то это справедливо не только для C++
К сожалению, в дотнете не так шоколадно, из-за того, что если тип по некоторому сценарию нужен для как ref, то такую декомпозицию с его участием в других местах легковесной не назовешь, ибо он везде пойдет как ref, добавляя уровень косвенности. В общем случае для дотнета описанный сценарий крайне вреден.
S>генерики они другие. На темплейтах можно делать то, что нельзя на генериках и наоборот.
Генерики только имеют одно преимущество, позволяют оперировать с заранее неизвестным типом в рантайм, создавая экземпляры через рефлексию. Это такой же плюс, как и любые другие сценарии вокруг рефлексии. Так же удобны ограничения в виде специального синтаксиса, но ограничения можно использовать и в С++ через ср-ва языка, и даже эти ограничения могут поразнообразнее, но синтаксис не заточен именно под ограничения. Во всех остальных случаях генерики неизмеримо беднее.
S>Например, был жестоко обломан тем что темлейт функции-мемберы не могут быть виртуальными
Потому что никакой динамики, а только статика. И первый вызов такого метода у генерика оч дорогой. И почему жестоко-то? Приведи задачу, посмотрим, что под нее подходит. На шаблонах же что угодно делать можно, включая параметризируемую базу. Мне ни разу не нужна была упомянутая тобой фича в шаблонах, хотя в генериках без нее вообще никак. Но в генериках и выбора особого нет.
S>Вот еще пример, рекурсивный полиморфизм невозможно юзать во времени выполнения в C++, но вполне работает в C#. Если что — я об Purely Functional Data Structures (Queues based on implicit recursive slowdown).
Не уверен, что это так, если речь не идет о брутфорсной рефлексии времени исполнения. Приведи пример на C#. Потому как если наоборот, то в плане метаинформации времени компиляции, ситуация в С++ всяко получше. Ну и есть такая фишка, как т.н. статические визиторы. Т.е. это аналогичный обычному визитору механизм, полностью заресолвленный в статике там, где в аналогичном месте в C# он был бы заресолвлен лишь в динамике через двойную диспетчеризацию.
Здравствуйте, Ikemefula, Вы писали:
I>Нативный софт начали писать еще в 80х [...]
Щито???
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, gandjustas, Вы писали:
V>>По моим наблюдениям за глюкавостью дотнетных программ, они ловятся на совершенно детских тестах: например часто при попытке сохранить файл в директорию, защищенную от записи или почти в 100% случаев, при исчерпании какого-нить ресурса (кол-ва сокетов, поверхностей для рисования, свободного места на диске). Такое ощущение, что дотнетчики поголовно пишут код из расчета "всё будет хорошо", проверяя максимум контракты на входные параметры методов, во всех остальных случаях тупо плюя эксепшен, который (удивительно!) никто нигде не ждет. G>Так это же прекрасно, если вылетит exception то его быстрее поправят чем если он не вылетит. Писать в стиле let it crash полезно даже для десктопа, потому что позволяет быстро повесить обработку exception на верхнем уровне и выдавать пользователю адекватное сообщение.
А толку, если программа после этого перешла в невалидное состояние, показав пользователю сообщение? Где уж тут let it crash? Это возможно только в транзакционной по духу системе, так что не раскидывайся терминами, которых не понимаешь.
V>>Понятие безопасного к исключениям кода — это нечто из другой реальности,\ G>Именно, так как в .NET exception может вылететь где угодно. Пытаться писать код который не кидается исключениями — слишком затратно и абсолютно бесполезно.
Наоборот, при наличии механизма GC организовать атомарность смены состояний можно оч дешево, в сравнении с нейтивом. Но в твоем коде будут точно такие же мины, это уже понятно по твоему ответу. Ты показал, что не в курсе о чем речь.
Не поинтересуешься у тестовой команды, какова доля негативных тестов в общей доле тестов? Если меньше 70%-80% (грубо), то при игнорировании устойчивости к исключениям в вашей дисциплине кода, мы обсуждаем сейчас стандартный дотнетный говнокод, с детскими ошибками внутри.
V>>отсюда дотнет — просто рассадник наведенных ошибок (по опыту своей помощи в ловле ошибок коллег), бо после первой же обработанной (якобы обработанной) ошибочной ситуации, отваливается работоспособность в другом месте, потому как один или несколько объектов остаются в некоем промежуточном невалидном состоянии. G>Ты уже взаимоисключающие вещи писать начал. То тебе не нравится что валятся эксепшены, то не нравятся как их обрабатывают.
Ладно, про безопасный к исключениям код мы не слышали, отсюда ответы совершенно невпопад. Давай пока прервемся, а вернемся к теме лишь тогда, когда будет что сказать, чтобы ветка обсуждения зря не пропадала.
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Здравствуйте, gandjustas, Вы писали:
ГВ>>>Это как раз очень простая ситуация. Врубись: я держу ссылку на объект, предполагая, что он кому-то нужен. Но этот кто-то этот самый объект сейчас "выкидывает". В unmanaged произойдёт "ой" из-за внезапного delete, а в managed — будет тишина и я буду продолжать работать с никому не нужным объектом.
G>>Да, и managed программа будет работать и работать корректно.
ГВ>Разницу между "корректно" и "без выбрасывания исключений" надо объяснять?
Да, опиши что такое "корректно". Почему ты считаешь некорректным держать ссылку на объект? Это как-то повлияет на результат?
G>>В unmanaged в лучшем случае упадет. Разницу понимаешь? ГВ>Естественно, понимаю.
Похоже что нет. Хотя это зависит от твоего понимания корректности.
ГВ>[...]
G>>Тут получается что просто не договорились между managed и unmanaged о tread safety.
ГВ>Вот, живой пример вреда code samples: собеседник начинает делать далеко идущие выводы из ничего. Код сугубо иллюстративный и показывает только то место, где возникала потеря объекта данных.
Есои он полностью не описывает ситуацию тогда зачем ты его привел?
ГВ>В реальности и сам код был сложней, и ещё довольно сложная логика перезапуска потоков, из-за которой, в общем, всё и случилось. Но к тому, на что я хотел обратить внимание, это не относится. А про однопоточность unmanaged всем и так было известно.
В таких случаях надо делать вокруг unmanaged кода wrapper, который будет проверять предусловия. Вообще стоит почитать гайдлайны перед тем как писать такое.
А то получается что ты низкую квалификацию писавшего код на C# выставляешь за недостаток языка.
Здравствуйте, Ikemefula, Вы писали:
I>>>Прикол в том, что средний программист уже не способен писать на С++. Вот это действительно прикол. А если учесть, что на менеджед пишется примерно 99% всех проектов, то это да, большой прикол. V>>Мде? А я вижу, что практически все популярные программы на нейтив, даже которые опенсорсные. I>и много этих популярных программ ?
Тулзы типа SVN, игрушки, OpenOffice, Skype, компиляторы (без счёта), мессенджеры, браузеры, оболочки (KDE, Gnome, Explorer), графические пакеты... Ты, правда, хочешь, чтобы их тут перечисляли?
>>Попробуй на досуге набрать в гугле "новости софта", или зайти на любой пиратский торрент и посмотреть в топах, что народ качает. Дотнет там оч редко, только в утилитах каких-нить, администраторских.
I>Расклад по тому, что нынче пишется в каких объемах можно сделать тупо по количеству вакансий. Как то я не вижу значительного кол.ва вакансий на с++ и не вижу, что бы ЗП в с++ отражали спрос на с++
Нативный софт часто пишется стабильными долгоиграющими командами, отсюда и относительно небольшое количество вакансий. З/п отражают не количество разрабатываемого софта, а совсем другое.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Ну а теперь, давай сделаем простую индукцию. Код принципиально рассчитан на работу в одном потоке, следовательно, хитрых смарт-пойнтеров в нём делать не будут. Просто ни к чему. А значит, вызывающий код с некоторой очень ненулевой вероятностью будет выглядеть примерно так:
ГВ>
ГВ>void processData() {
ГВ> while(...) {
ГВ> delete m_pData;// <- вот тут и будет "ой"
ГВ> m_pData = callReadingCode();
ГВ> int x = m_pData->prop1;
ГВ> // ...
ГВ> }
ГВ>}
ГВ>
Я, наверное, какой-то очень странный. Мне совершенно неочевидно, почему начинать цикл нужно именно с delete, и кто будет удалять результат последнего чтения (я в курсе про валидность первого вызова delete до инициализации m_pData).
Я бы ожидал чего-то вроде
Впрочем, это не совсем важно. Важно то, что вызов delete, даже в таком цикле — относительно редкая штука. Тело цикла будет прекрасно себе работать с уже убитым объектом, а если повезёт — то и со следующим, размещённым на его месте.
ГВ>За счёт разваливания разметки динамической памяти (хипа). Да-да, ты не ослышался.
А-а. Ну тогда ладно. Интересно только, какая избыточность в хипе тратится на метаинформацию о распределённых блоках, чтобы можно было определить такие косяки.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, gandjustas, Вы писали:
ГВ>>>>Это как раз очень простая ситуация. Врубись: я держу ссылку на объект, предполагая, что он кому-то нужен. Но этот кто-то этот самый объект сейчас "выкидывает". В unmanaged произойдёт "ой" из-за внезапного delete, а в managed — будет тишина и я буду продолжать работать с никому не нужным объектом. G>>>Да, и managed программа будет работать и работать корректно. ГВ>>Разницу между "корректно" и "без выбрасывания исключений" надо объяснять?
G>Да, опиши что такое "корректно". Почему ты считаешь некорректным держать ссылку на объект? Это как-то повлияет на результат?
Вход: число N.
Выход: N x 2.
Пример неправильного выхода без выбрасывания исключения: N x 2 + 1.
G>>>В unmanaged в лучшем случае упадет. Разницу понимаешь? ГВ>>Естественно, понимаю. G>Похоже что нет. Хотя это зависит от твоего понимания корректности.
Ну похоже, так похоже. Мне-то что?
ГВ>>[...]
G>>>Тут получается что просто не договорились между managed и unmanaged о tread safety.
ГВ>>Вот, живой пример вреда code samples: собеседник начинает делать далеко идущие выводы из ничего. Код сугубо иллюстративный и показывает только то место, где возникала потеря объекта данных. G>Есои он полностью не описывает ситуацию тогда зачем ты его привел?
Очевидно, затем, чтобы показать, как терялся объект данных, сгенерированный unmanaged-кодом. Только для этого. Поверь, советов по проектированию я спрашивать не собирался.
ГВ>>В реальности и сам код был сложней, и ещё довольно сложная логика перезапуска потоков, из-за которой, в общем, всё и случилось. Но к тому, на что я хотел обратить внимание, это не относится. А про однопоточность unmanaged всем и так было известно.
G>В таких случаях надо делать вокруг unmanaged кода wrapper, который будет проверять предусловия. Вообще стоит почитать гайдлайны перед тем как писать такое.
Ты правда, прочёл то сообщение, которое обсуждаешь?
G>А то получается что ты низкую квалификацию писавшего код на C# выставляешь за недостаток языка.
Мой тебе добрый совет: не надо рассуждать о чужой квалификации с через третьи руки.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Sinclair, Вы писали:
S>Я, наверное, какой-то очень странный. Мне совершенно неочевидно, почему начинать цикл нужно именно с delete, и кто будет удалять результат последнего чтения (я в курсе про валидность первого вызова delete до инициализации m_pData). S>Я бы ожидал чего-то вроде [...]
Ну, я сознательно усложнил. В твоём варианте всё будет ещё проще: появится утечка, а по ней уже легко выйти на причины.
ГВ>>За счёт разваливания разметки динамической памяти (хипа). Да-да, ты не ослышался. S>А-а. Ну тогда ладно. Интересно только, какая избыточность в хипе тратится на метаинформацию о распределённых блоках, чтобы можно было определить такие косяки.
Довольно значительная (навскидку не скажу). Но это классический хип, в случае кастомных хипов объёмы метаданных меньше, и проявления ошибок, соответственно, тоже отличаются.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
V>>>Мде? А я вижу, что практически все популярные программы на нейтив, даже которые опенсорсные. I>>и много этих популярных программ ?
ГВ>Тулзы типа SVN, игрушки, OpenOffice, Skype, компиляторы (без счёта), мессенджеры, браузеры, оболочки (KDE, Gnome, Explorer), графические пакеты... Ты, правда, хочешь, чтобы их тут перечисляли?
Если не считать игрушек, то это все слабенькие примеры. А вот только корпоративных сайтов будет в разы бОльше чем мессенджеров, браузеров, оболочек, графических пакетов и тулзовин вроде SVN вместе взятых. Да-да.
Здравствуйте, Ikemefula, Вы писали:
V>>>>Мде? А я вижу, что практически все популярные программы на нейтив, даже которые опенсорсные. I>>>и много этих популярных программ ? ГВ>>Тулзы типа SVN, игрушки, OpenOffice, Skype, компиляторы (без счёта), мессенджеры, браузеры, оболочки (KDE, Gnome, Explorer), графические пакеты... Ты, правда, хочешь, чтобы их тут перечисляли? I>Если не считать игрушек, то это все слабенькие примеры. А вот только корпоративных сайтов будет в разы бОльше чем мессенджеров, браузеров, оболочек, графических пакетов и тулзовин вроде SVN вместе взятых. Да-да.
За время работы в индустрии у меня сложилось устойчивое убеждение, что "корпоративный сайт" (а чуть раньше — "корпоративная база данных") — это такая штука, написать которую просто дело чести для каждого программиста и тем более — для разработчика инструментальных средств. Почти уверен, что можно найти корпоративные [что-то] на шелле.
Собственно, корпоративный софт не релевантен популярности в данном случае, поскольку пишется под требования определённого, достаточно узкого круга лиц, под более или менее определённую аппаратуру, системное ПО и т.п. Ну вот возьму я, напишу для себя нечто на batch-файлах, ну и что?
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Ikemefula, Вы писали:
I>>>Нативный софт начали писать еще в 80х [...] ГВ>>Щито??? I>Офис, вындоус и куча всякой всячины тянется ажно оттуда.
Ты не понял. 80-е — это слишком недавно. Когда язык Си был придуман?
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Sinclair, Вы писали:
V>>Не вижу здесь чего-то удивительного. Разработчик с 3-х летним опытом всяко должен отличаться от разработчика с опытом в год. Как раз, по моим наблюдениям, в хорошей среде программист С++ за примерно 3 года овладевает всеми обсуждаемыми приемами на уровне мозжечка. А если учесть, что средний стаж программистов в наше время поболе 5-ти лет, я вообще не вижу проблем. S>Осталось показать код. А то получается, что теоретически программисты владеют всеми приёмами на уровне мозжечка, а на практике пишут совершенно без них.
Только что с предыдущего проекта сделал глобальный поиск по new:
std::auto_ptr<AsyncRestartThread> thread (new AsyncRestartThread (*this));
restartMutex (new Mutex) // приватное поле
std::auto_ptr<SessionImpl> sessionPtr(new SessionImpl(this, isDefault));
impl (new Impl()) // приватное поле
boost::shared_ptr<ListenersState> state (new ListenersState);
obBroadcastQueue_.reset(new BroadcastQueue());
ordersBroadcastQueue_.reset(new BroadcastQueue());
std::auto_ptr<TradingState> statePtr (new TradingState ());
std::auto_ptr<Series> seriesPtr(new Series(makeSeriesId(item.series), *instrumentClass));
return MultithreadGuardPtr(new MultithreadGuard(callback));
std::auto_ptr<Entry> entry(new(mem) Entry()); // а это свой аллокатор, происходит inplace new
boost::scoped_array<char> tmp(new char[recvLen]);
broadcastThread_.reset(new BroadcastThread(*this));
В голый указатель шел результат new только в приватные поля объектов.
Кстати, самого сие нехило удивило (мягко сказано!!!), что в таком приличном проекте так редко используется new, приведена примерно треть от всех ситуаций (слишком "говорливые" идентификаторы был вынужден убрать, но в убранном все тоже самое). В остальных случаях объекты идут по значению в полях других объектов, либо как временные на стеке, т.е. относительно общего числа типов и сценариев, необходимость каждый объект-молекулу размещать на куче крайне и крайне редка. (хотя, некоторые идут в контейнерах, а те хранят свои ячейки на куче, справедливости ради). Но всё равно, иногда полезно собирать статистику, всё даже лучше, чем казалось.