к чему это? коды ошибки 1..63 вообще-то за системой зарезервированы. Как и коды 128..255. Вот и остаются 64..127.
к тому, что информации это тебе никакой не даст, ну вышла твоя программа с кодом 66 - и что это тебе даст, если ты все проверки сделал с exit( 66 );?
оберни в макрос, если не хочешь писать.
все равно надо руками писать, хоть с макросом, хоть без
Кроме как рухнуть, программе ничего и не остаётся
при этом она может выдать полезную информацию, я на работе вообще приделал автоматическую отсылку отчетов, так что если у кого вдруг падает, то я сразу вижу где и почему, к сожалению даже хороший код не защищает от крешей в сторонних библиотеках, например
Это не подходит для системного софта, избыточные проверки, потому и едим кактус. А для прикладного так и надо, потому что он пишется согласно быстрых изменений рынка и требований пользователей, нет времени сегфолты исследовать
используй обёртки над массивами, которые проверяют индекс. ну если у тебя нет времени для написания корректных алгоритмов, а использовать готовые ты не умеешь.
к тому, что информации это тебе никакой не даст, ну вышла твоя программа с кодом 66 - и что это тебе даст, если ты все проверки сделал с exit( 66 );?
ну плюну в stderr номер строки и имя файла. Или ещё что-то.
все равно надо руками писать, хоть с макросом, хоть без
ну что делать... java-код тоже писать надо...
при этом она может выдать полезную информацию, я на работе вообще приделал автоматическую отсылку отчетов, так что если у кого вдруг падает, то я сразу вижу где и почему
в сишечке это тоже можно. Но проще доказать, что выхода не будет, и проверка потому не нужна. Например в моём коде выше цикл просто не выполняется, если есть выход. Потому условие избыточно, и в общем-то всё равно. какой код, и какое сообщение НИКОГДА не выводится.
к сожалению даже хороший код не защищает от крешей в сторонних библиотеках, например
ну... тут уж ничего не попишешь. кроме багрепортов авторам либы.
exit(3) это не велосипед, а стандартная функция. про assert.h я в курсе, но эти костыли не очень удобны (например в случае файлов я-бы хотел ещё и errno почитать)
ну плюну в stderr номер строки и имя файла. Или ещё что-то.
рад, что тут мы договорились
ну что делать... java-код тоже писать надо...
но руками ассерты расставлять не надо
в сишечке это тоже можно
ну так я и пишу на работе на С и С++ )
ну... тут уж ничего не попишешь. кроме багрепортов авторам либы.
я в таких случаях пишу патч, пересобираю библиотеку у себя и шлю патч авторам, а подобные автоматические отчеты сильно экономят время - не надо просить данные у клиентов, шаги, чтоб повторить креш и пр.
Старые пердуны преподаватели (т.е. даватели «препы») из радиотехнических типа «университетов» (это типа ПТУ, только с зубрением теорем по матану) не любят сишников, поскольку
1. Старперы-неудачники считают себе куль-системными программистами.
2. Старперы-неудачники, кроме поверхностных знаний типа ассемблера СМ-4 и паскакаля, языками программирования не владеют.
Поэтому и не любят никому не нужные в реальной жизни препы-лузеры тех, кто реально знает нормальный язык системного программирования.
Есть много операционных систем на с++, в том числе и юникс-подобные, нет никаких принципиальных проблем переписать линукс на с++. Более того, рано или поздно его начнут собирать с++ компилятором и вводить потихоньку с++ фичи, как это происходит с gcc.
Обобщенные коллекции и алгоритмы; обработка ошибок; освобождение ресурсов локальных для функции; namespaces.
полиморфизм и наследование реализуется в C++ через дважды косвенный вызов
Точно так же, как и в любом другом языке включая С. И если отключить rtti и в классе будет один виртуальный метод, наверняка компилятор уберет таблицу виртуальных методов, по крайней мере я не знаю, что ему может помешать это сделать. Ты ведь не предлагаешь в каждом инстансе хранить указатели на все виртуальные функции, реализуя полиморфизм на С?
Т.е., даже если тебе надо всего-лишь сравнить два целых числа, тебе придётся извлечь адрес из VT, а потом по нему перейти. Очевидно, что это на порядок дороже простого cmp/jnz. Даже без учёта того, что весь конвейер придётся похерить.
В С это будет аналогично выглядеть, если тебе нужен полиморфизм. Если не нужен, то его и в С++ не будет и это будет простая, потенциально встраиваемая функция.
У плюсов есть киллер-фича, в них почти нет конструкций с неочевидным оверхедом, все можно понять вплоть до машинных инструкций, это позволяет писать максимально оптимизированный для компьютера код. Я других популярных языков, предлагающих это, не знаю. Только ассемблер, с и с++.
Язык может предоставлять удобные абстракции, упрощающие соответствующие задачи. Как пример - сборщик мусора значительно упрощает управление памятью. Умные указатели тоже упрощают, хотя и не настолько. Шаблоны позволяют отказаться от большинства случаев использования макросов и иметь гораздо более контролируемые трансформации кода. А так, конечно, хоть на ассемблере пиши, хоть на брейнфаке, все можно спихнуть на проблемы быдлокодера.
Да ладно, при желании на чем угодно можно. И на плюсах, и на барсике, и на додиез (см. сингулярити). Только вот почему-то ничего кроме написанного на С тольком не взлетело. Вот так странно.
Только вот почему-то ничего кроме написанного на С тольком не взлетело. Вот так странно.
а ты скажи, что «взлетело» из того, что было написано хотя бы начиная со второй половины 90-х, место уже занято, а когда его занимали особо вариантов не было, вот тот же Haiku весьма хорош, но он мог бы взлететь, только если б сообщество опенсорс не имело линукс
ну тот же хайку и колибри в лучшем состоянии чем тот же сингулярити, который нахрен никому не вперся. Хотя казалось бы, впервые, дрова могут шарпервы быдлокодить!11
Ну потому что дженерики в Java на уровне языка, а не VM. Поэтому все приведенные примеры фактически эквивалентны, ибо демонстрируют по сути одно и то же.
Теперь можете попробовать C# и возрадоваться, ибо в .net дженерики на уровне VM, и все это будет работать. Только это тоже не всегда хорошо, но вас-то порадует.
Так, пишу _прикладные_ программы на O-C 2.0 для своего личного яМобилко.
На жизнь я зарабатываю «жабабыдлокодингом» (с)(тм).
Гуманитарчиков стали уже разгонять - пора «радиотехнические университеты» снова преобразовать в ПТУ. С переподготовкой проФФессоров-матанщиков в дворники вместо гастарбайтеров.
давай на тех примерах, что я привел, расскажи чем это плохо
«Покажи мне на тех примерах, на которых это хорошо, чем это плохо.» :р
Хотя показать все равно можно.
1) В случае дженериков на уровне VM имеем лишние сущности и проблемы с иерархией типов и кастингом. Нужно различать дженерические и соответствующие им недженерические типы (ArrayList<T> vs ArrayList) - две сущности вместо одной. Потом вопрос, кого от кого из них наследовать, чтобы можно было легко кастовать любой из них к любому. А также в качестве сюрприза: ArrayList<Object> никак не связан с ArrayList<String>, хотя String наследуется от Object. Т.е. два независимых контейнера для двух связанных сущностей. Ведет к очевидным извращениям.
2) Если создаются прототипы методов для одинаковых контейнеров с разными дженерическими типами - это какая-то проблема реализации. Не вижу реальной необходимости в такой конструкции. Но даже если есть жуткая нужда реализовать разную логику с контейнерами в зависимости от хранимого типа, никто не мешает проверить первый элемент списка через instanceof и передать управление в зависимости от этого другим методам. Т.е. нет никакой необходимости, чтобы дженерики участвовали в сигнатуре метода. Ну да, не статика, а рантайм, разве что.
3) Вместо массива дженерических объектов можно создать массив соответствующих недженерических объектов. Если люто нужна проверка на тип, можно его проверять в коде. Ну да, тут минус - анализ будет в рантайме, а не статический. Согласен. Но никто не запрещает использовать тот же List фиксированного вместо массива, а вот список дженерических объектов создать не проблема. Вряд ли будет большой оверхед.
«Покажи мне на тех примерах, на которых это хорошо, чем это плохо.» :р
ну да, можно даже на банальном if написать индусокод, это не означает, что if что-то плохое
ArrayList<Object> никак не связан с ArrayList<String>, хотя String наследуется от Object. Т.е. два независимых контейнера для двух связанных сущностей. Ведет к очевидным извращениям.
предотвращает очевидные извращения, ты хотел сказать
никто не мешает проверить первый элемент списка через instanceof и передать управление в зависимости от этого другим методам
костыли и извращения на марше
Вместо массива дженерических объектов можно создать массив соответствующих недженерических объектов
еще одни костыли, ты решил еще раз рассказать как в Java все убого? спасибо
А также в качестве сюрприза: ArrayList<Object> никак не связан с ArrayList<String>, хотя String наследуется от Object.
И это очень даже правильно, что никак не связанны, т.к. ArrayList - это mutable объект. Посмотрите как в Scala variance для generics работает и какие там mutable/immutable коллекции.
предотвращает очевидные извращения, ты хотел сказать
На самом деле, в данном случае просто без разницы, работает одинаково в обоих случаях. Неудачный пример, да.
Сейчас бы вспомнить, на чем пришлось извращаться в дженериках в C#, и что легко делалось в Java. Что-то точно было, но уже не помню. Жалко, минус аргумент. :)
С рефлекшеном и так понятно, что без дженериков в vm все куда проще.
костыли и извращения на марше
Какие юзкейсы - такие и решения. Я не вижу никакого практического смысла в создании двух методов с одним и тем же именем и разными дженерическими коллекциями в качестве аргументов. Точно так же как зачем нужен именно массив списков, а не другая структура данных. Если будут конкретные примеры где это было нужно - поверю. А если нет - для любой платформы можно придумать пример, который она не умеет.
Если будут конкретные примеры где это было нужно - поверю. А если нет - для любой платформы можно придумать пример, который она не умеет.
тут выше говорили, что ООП вообще в ЯП не нужно - на практике через void* в С все можно сделать, я не собираюсь участвовать в подобного рода дискуссиях, дженерики в Java ограничены и плохо вписываются в сам ЯП - очевидный факт, я привел примеры (далеко не все возможные), кому-то хватает того, что есть - рад за них, как и за тех кому хватает void*
П.С. а примеры (попыток) использования легко гуглятся, например, по java+generics+array
Точно так же, как и в любом другом языке включая С.
в С это только один из способов.
И если отключить rtti и в классе будет один виртуальный метод, наверняка компилятор уберет таблицу виртуальных методов, по крайней мере я не знаю, что ему может помешать это сделать. Ты ведь не предлагаешь в каждом инстансе хранить указатели на все виртуальные функции, реализуя полиморфизм на С?
может и предлагаю - от задачи зависит.
Т.е., даже если тебе надо всего-лишь сравнить два целых числа, тебе придётся извлечь адрес из VT, а потом по нему перейти. Очевидно, что это на порядок дороже простого cmp/jnz. Даже без учёта того, что весь конвейер придётся похерить.
В С это будет аналогично выглядеть, если тебе нужен полиморфизм. Если не нужен, то его и в С++ не будет и это будет простая, потенциально встраиваемая функция.
полиморфизм он разный бывает - скажем у меня два типа элементов, для списка, и для дерева. И мне нужен operator<() для их сравнения. Очевидно, я его делаю виртуальным, ибо точно не знаю, как это сравнивать. Но что делать, если ключом в обоих случаях является целое число? Я сомневаюсь, что компилятор сможет это обнаружить. А всё потому, что хотя элементы в коллекциях разные, сами их данные таки одинаковые. Но у меня нет двух полиморфизмов, у меня только один.