Оживший юзерпик - Ух ты!
сент. 9, 2014
09:40 am - Ух ты!
Before going to the three-day Groovy-sabbath, I was going through some old C/C++ code and came across one of the most brilliant ways to initialize a pointer with an"undefined" value, which would work on a platform where 0x0 is a valid address for data. The code reads:
T* pT = (T*)&pT;
I wonder if they still teach students about fundamentals of this sort. Or do they start with thread pools and dynamic languages, disregarding the basic physics of software development?
Я бы не допёр :)
Comments:
Mass Action
Групповое действие над комментариями:
(Перевожу на русский - использование не-managed ЯП на платформах, отличных от Эльбруса - мазохизм.)
И, кстати, такое должен ловить статический анализатор. Которых, БЛЯДЬ, для си до сих пор, оказывается, тоже нет.
И - ладно, я готов простить людям любовь к си - сам таким был. Но язык с таким стажем и отсутствие внятного статического анализа - это КАК?!
Чтобы узнать, что такое статический анализ, надо скачать IntelliJ Idea, кинуть в него любой java opensource классов на 100, прогнать анализатор и потерять дар речи. А потом задаться вопросом - нахуя программировать на языке, для которого нет такого инструментария.
http://en.wikipedia.org/wiki/Lint_%28so
И кстати, там есть ссылочка на список статических анализаторов для всего: http://en.wikipedia.org/wiki/List_of_to
У C++ и С есть свои сильные стороны, отнюдь не завязанные на производительность.
По каким-то загадочным причинам ни одного "managed" языка, имеющего аналогичные сильные стороны, в широком применении не появилось. Хотя тот же C++ постепенно двигается в похожем направлении.
1. Возможность выбора между OOP и generic programming.
2. Возможность сочетания одного с другим
3. Возможность явного управления памятью там, где это нужно (во многих случаях это - большое преимущество)
4. Деструкторы вместо финализаторов
5. Полноценное множественное наследование (есть много паттернов, где его применение сильно упрощает жизнь)
5. Возможность доступа к низкоуровневым операциям ОС и аппаратуры
C:
1. Простой и чёткий синтаксис - при соблюдении элементарной гигиены, разумеется
2. Возможность доступа к низкоуровневым операциям ОС и аппаратуры
3. Высокая степень предсказуемости программы, сравнительно простая отладка при использовании современных инструментов
4. Один язык реально для любого окружения - поддерживается действительно везде
В то же самое время действительно сильная "C++"-ная команда с точки зрения квалификации будет иметь заметно более высокий класс по сравнению с действительно сильной "Java"-командой. С этим IMHO тоже глупо спорить. И у каждой из них есть сугубо своя рыночная ниша.
И да, 75% реально работающего кода - дрянь, худо-бедно отлаженная толпой идиотов. Увы.
Не согласен, буду глупо спорить.
Согласен :)
Глядишь, и сам поумнею.
Кстати, п.2 действительно спорный, отсюда и IMHO ;)
IMHO: сложная система требует в первом приближении одинаковой квалификации программистов без особенной зависимости от языка/технологии. Сложнее ли типичная система, написанная на плюсах, типичной системы, написанной на Java?
Не претендую на всеобщность выводов, но лично по моим наблюдениям и ощущениям при в целом сравнимом порядке сложности код "типичной" системы, написанной на C++ и смежных средствах, имеет заметно меньший физический объём и заметно большую смысловую плотность - по сравнению с аналогом на Java.
При этом я бы предложил не рассматривать случаи, когда язык и иные инструменты выбирался без оглядки на задачу (таких дурных примеров масса - скажем, не является уникальной банковская аналитика на C++ или, скажем, система мониторинга и управления дисковым массивом на Java).
Так вот, более высокая смысловая плотность качественного кода на C++ по сравнению с качественным же кодом на Java, в сочетании с немалым количеством способов непреднамеренно выстрелить себе в ногу на C++, реально требует от хорошего C++ программиста заметно более высокой технической квалификации по сравнению с хорошим же программистом на Java.
"некоторые программеры считают, что мировые запасы круглых скобок сильно ограничены".
Код на Java (или, скажем, на C#) - рыхлый, с заниженной (в среднем некомфортной) смысловой плотностью и избыточным многословием. Это не мои фантазии, данное мнение разделяют очень многие. Для высокоуровневого языка, да ещё и "управляемого", рыхлость - это скорее недостаток.
К слову, некоторые другие языки в Java-экосистеме с этим недостатком успешно борются, а некоторые (тот же Closure) его лишены напрочь. Сложный код на Schema/Closure иногда как раз хочется искусственно растянуть - но это хотя бы возможно физически.
- геттерам и сеттерам - это можно игнорировать. при сложившихся (кстати, ещё одно ужасно слабое место си) правилах написания этих методов читать их требуется в исключительных случаях.
- инстанцииации абстрактных классов в выражении вместо передачи кодовых констант. это - реальная претензия, но не со стороны си её применять, вообще-то. Там это вообще только как пойнтер на функцию, что уж совсем нечитаемо.
всё.
При этом ява поддержана БЕШЕНЫМ количеством инструментария, который нивелирует эту хрень в ноль. Те же геттеры-сеттеры генерятся в два клика. Та же инстанциация с доопределением метода вставляется эклипсом совершенно автоматически. но читать немного неудобно, да. Сколько их в коде? Одна на 10 классов?
Просто предыдущим текстом вы как раз напрямую подтверждаете мои же тезисы.
Тех самых программистов класса "программер стоит почти столько же" как раз и нельзя включать на серьёзных ролях в команду, которая занимается разработкой на C++. Только в роли подмастерья, под зоркий контроль старших (и заметно более жадных по деньгам) товарищей.
Должный уровень профессионализма как раз и позволяет
(а) минимизировать те самые SIGSEGV
(б) за разумное время (а с современными инструментами - и вовсе быстро) разруливать порчу стеков
(в) писать стабильно работающие MT-программы и успешно устранять просочившиеся-таки ошибки.
А так - отдельные "талантливые" программисты и на Java нередко умудряются прострелить себе ногу, успешно устроив трудноуловимую утечку памяти (еще хуже - других, внешних ресурсов) в большой программе или написав алгоритм, который начинает зверски тормозить при мало-мальском увеличении объёмов данных. В каждой среде - свои сложности и пути их преодоления.
Я уж молчу про дизайн структур данных. После полугода работы с GC ручное управление памятью вызывает ступор не меньший, чем предложение пересесть с авто на лошадь.
Что не отменяет того, что более половины кода -- ассэмблер. Как, в общем, и на SIM-картах (если считать не только конечные приложэния). При том, что функцыонал приложэний сим-карт -- крайне ограничен.
Какой он undefined, если он указывает на pT? На вполне конкретный pT, который, после записи, будет существенно менять поведение программы, который никогда не вызовет SEGV если просто взять с него int?
И да, напомню всем, что адрес 0 или (void *)0 -- является по стандарту Си неопределённым адресом, не указывающим ни на какой правильный объект, при этом (тожэ по стандарту Си) -- его битовое представление совсем не обязано состоять из нулей.
Т.е. 0 (он жэ NULL, макрос для NULL обычно и определён как (0)) -- это как раз и есть undefined pointer. Независимо от того, нужэн ли программ адрес 0x0.
Такие волшебные платформы, где malloc() или new могут вернуть 0 и это не будет ошибкой - сами по себе не совсем прямые.
Как решение описанной проблемы IMHO можно завести глобальную переменную, а затем макрос NULL сделать равным взятию указателя от такой переменной. Тогда немалая часть кода заработает автоматически, кроме, естественно, старого доброго "void *ptr = 0;" ;)
The new C++09 nullptr keyword designates an rvalue constant that serves as a universal null pointer literal, replacing the buggy and weakly-typed literal 0 and the infamous NULL macro. nullptr thus puts an end to more than 30 years of embarrassment, ambiguity, and bugs. The following sections present the nullptr facility and show how it can remedy the ailments of NULL and 0.
но зачем.
- Какой кат купить?
- Купи каяк!
:)
Fundamentals of this sort не надо учить. Это не fundamentals, а очень злое колдунство, изучать которое надо не студентам, а суровым бородатым чернокнижникам, которым себя уже не жалко.Способы открывания портала в ад надо прятать от неофитов, они еще не понимают, что там правда неприятно.
Это "злое колдунство", кстати, прекрасно выводится из основ, коим действительно должны учить студентов.