Ух ты!

Sep. 9th, 2014 09:40 am
tobotras: (Default)
[personal profile] tobotras
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?


Я бы не допёр :)

Date: 2014-09-09 05:47 am (UTC)
vitus_wagner: My photo 2005 (Default)
From: [personal profile] vitus_wagner
Вот если бы в С/С++ было принято делать проверку указателя на неопределенность маросом IS_NULL(p), а не сравнением p==NULL....

Date: 2014-09-09 05:59 am (UTC)
From: [identity profile] tzirechnoy.livejournal.com
Какая разница?

Date: 2014-09-09 06:05 am (UTC)
vitus_wagner: My photo 2005 (Default)
From: [personal profile] vitus_wagner
Тогда просто переопределив этот макрос можно было перейти от схемы "неопределенный указатель равен нулю" к "неопределенный указатель равен адресу переменной, в которой он хранится".

Date: 2014-09-09 10:14 pm (UTC)
From: [identity profile] zaitcev.livejournal.com
Сломается после первого присваивания.

Date: 2014-09-09 12:53 pm (UTC)
From: [identity profile] beldmit.livejournal.com
В стандарте 2011-го года в эту сторону сделали некоторые телодвижения.

Date: 2014-09-09 05:52 am (UTC)
From: [identity profile] dz.livejournal.com
Люди, которые в 21-м веке жрут с кинжала, должны гордиться порезами морды, я считаю.

(Перевожу на русский - использование не-managed ЯП на платформах, отличных от Эльбруса - мазохизм.)

И, кстати, такое должен ловить статический анализатор. Которых, БЛЯДЬ, для си до сих пор, оказывается, тоже нет.

Date: 2014-09-09 06:08 am (UTC)
From: [identity profile] d1f.livejournal.com
Зачем? Не мешайте нам стрелять себе в ногу!

Date: 2014-09-09 08:57 am (UTC)
From: [identity profile] dz.livejournal.com
Тогда нехер скулить. Свои бешеные пойнтеры нужно нести над головой гордо.

И - ладно, я готов простить людям любовь к си - сам таким был. Но язык с таким стажем и отсутствие внятного статического анализа - это КАК?!

Чтобы узнать, что такое статический анализ, надо скачать IntelliJ Idea, кинуть в него любой java opensource классов на 100, прогнать анализатор и потерять дар речи. А потом задаться вопросом - нахуя программировать на языке, для которого нет такого инструментария.

Date: 2014-09-10 03:01 pm (UTC)
From: [identity profile] dz.livejournal.com
Спасибо, обязательно посмотрю. Подозреваю, что с исходниками ядра оно не справится, но попытку сделать надо.

Date: 2014-09-18 07:48 pm (UTC)
From: [identity profile] ostapru.livejournal.com
Кстати, в качестве статического анализатора для "це" чем линт не устраивает?

http://en.wikipedia.org/wiki/Lint_%28software%29

И кстати, там есть ссылочка на список статических анализаторов для всего: http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis

Date: 2014-09-21 09:44 pm (UTC)
From: [identity profile] dz.livejournal.com
Вы видели статик аналайзер inellij Idea? Стоит посмотреть. После этого линт стыдно вообще вспоминать.

Date: 2014-09-09 06:52 am (UTC)
From: [identity profile] zinal.livejournal.com
Дело вкуса, знаете ли.
У C++ и С есть свои сильные стороны, отнюдь не завязанные на производительность.
По каким-то загадочным причинам ни одного "managed" языка, имеющего аналогичные сильные стороны, в широком применении не появилось. Хотя тот же C++ постепенно двигается в похожем направлении.

Date: 2014-09-09 08:56 am (UTC)
From: [identity profile] vm-lj.livejournal.com
какие именно?

Date: 2014-09-27 05:35 pm (UTC)
From: [identity profile] zinal.livejournal.com
C++:
1. Возможность выбора между OOP и generic programming.
2. Возможность сочетания одного с другим
3. Возможность явного управления памятью там, где это нужно (во многих случаях это - большое преимущество)
4. Деструкторы вместо финализаторов
5. Полноценное множественное наследование (есть много паттернов, где его применение сильно упрощает жизнь)
5. Возможность доступа к низкоуровневым операциям ОС и аппаратуры

C:
1. Простой и чёткий синтаксис - при соблюдении элементарной гигиены, разумеется
2. Возможность доступа к низкоуровневым операциям ОС и аппаратуры
3. Высокая степень предсказуемости программы, сравнительно простая отладка при использовании современных инструментов
4. Один язык реально для любого окружения - поддерживается действительно везде

Date: 2014-09-09 09:05 am (UTC)
From: [identity profile] dz.livejournal.com
"Дело вкуса" - это, извините, ответ любителя. Ответ профессионала опирается на стоимость производства и стоимость эксплуатации. Стоимость разработки на старых и новых яп различается на полпорядка. Может быть, у Си и есть сильные стороны, но на стоимости разработки они сказаться не способны.

Date: 2014-09-27 05:41 pm (UTC)
From: [identity profile] zinal.livejournal.com
Стоимость производства и эксплуатации, извините, в основном определяется стоимостью содержания команды, способной разрабатывать и сопровождать код. Средняя команда, работающая со сложным кодом на C++, стоит заметно дороже аналогичной команды, работающей, например, с Java или новомодной Closure. С этим спорить глупо.

В то же самое время действительно сильная "C++"-ная команда с точки зрения квалификации будет иметь заметно более высокий класс по сравнению с действительно сильной "Java"-командой. С этим IMHO тоже глупо спорить. И у каждой из них есть сугубо своя рыночная ниша.

И да, 75% реально работающего кода - дрянь, худо-бедно отлаженная толпой идиотов. Увы.

Date: 2014-09-27 06:21 pm (UTC)
From: [identity profile] zinal.livejournal.com
П.1, п.2 - можно поподробнее? Интересно мнение умного человека :)
Глядишь, и сам поумнею.

Кстати, п.2 действительно спорный, отсюда и IMHO ;)

Date: 2014-09-28 05:37 am (UTC)
From: [identity profile] zinal.livejournal.com
Пиво или там иная рюмка чая в нынешних обстоятельствах вполне организуемы ;)

Не претендую на всеобщность выводов, но лично по моим наблюдениям и ощущениям при в целом сравнимом порядке сложности код "типичной" системы, написанной на C++ и смежных средствах, имеет заметно меньший физический объём и заметно большую смысловую плотность - по сравнению с аналогом на Java.

При этом я бы предложил не рассматривать случаи, когда язык и иные инструменты выбирался без оглядки на задачу (таких дурных примеров масса - скажем, не является уникальной банковская аналитика на C++ или, скажем, система мониторинга и управления дисковым массивом на Java).

Так вот, более высокая смысловая плотность качественного кода на C++ по сравнению с качественным же кодом на Java, в сочетании с немалым количеством способов непреднамеренно выстрелить себе в ногу на C++, реально требует от хорошего C++ программиста заметно более высокой технической квалификации по сравнению с хорошим же программистом на Java.

Date: 2014-09-29 03:03 pm (UTC)
From: [identity profile] dz.livejournal.com
Смысловая плотность кода - это МИНУС, а не плюс. Это - снижение читаемости.

"некоторые программеры считают, что мировые запасы круглых скобок сильно ограничены".

Date: 2014-09-29 04:43 pm (UTC)
From: [identity profile] zinal.livejournal.com
Смысловая плотность, как некая характеристика, для конкретного программиста, читающего либо пишущего код, имеет комфортный (то бишь наиболее эффективный) именно для данного программиста диапазон.

Код на Java (или, скажем, на C#) - рыхлый, с заниженной (в среднем некомфортной) смысловой плотностью и избыточным многословием. Это не мои фантазии, данное мнение разделяют очень многие. Для высокоуровневого языка, да ещё и "управляемого", рыхлость - это скорее недостаток.

К слову, некоторые другие языки в Java-экосистеме с этим недостатком успешно борются, а некоторые (тот же Closure) его лишены напрочь. Сложный код на Schema/Closure иногда как раз хочется искусственно растянуть - но это хотя бы возможно физически.

Date: 2014-09-29 09:18 pm (UTC)
From: [identity profile] dz.livejournal.com
Неплотность явы, в основном, сводится к

- геттерам и сеттерам - это можно игнорировать. при сложившихся (кстати, ещё одно ужасно слабое место си) правилах написания этих методов читать их требуется в исключительных случаях.

- инстанцииации абстрактных классов в выражении вместо передачи кодовых констант. это - реальная претензия, но не со стороны си её применять, вообще-то. Там это вообще только как пойнтер на функцию, что уж совсем нечитаемо.

всё.

При этом ява поддержана БЕШЕНЫМ количеством инструментария, который нивелирует эту хрень в ноль. Те же геттеры-сеттеры генерятся в два клика. Та же инстанциация с доопределением метода вставляется эклипсом совершенно автоматически. но читать немного неудобно, да. Сколько их в коде? Одна на 10 классов?


Date: 2014-09-29 03:01 pm (UTC)
From: [identity profile] dz.livejournal.com
один программер стоит почти столько же. просто на яве не бывает "бля, мы месяц ебёмся, и вааще неясно, откуда этот sigsegv, и кто насрал в этот пойнтер". Собственно, синглтред на си можно терпеть - нагаженный стек ловится. А малтитред - ПИЗДЕЦ. Потому что ловится только через прочесть весь код построчно слева направо сверху вниз.

Date: 2014-09-29 04:53 pm (UTC)
From: [identity profile] zinal.livejournal.com
Мне не очень хочется что-либо тут доказывать, у каждого есть свой личный немаленький опыт как основа для суждений.
Просто предыдущим текстом вы как раз напрямую подтверждаете мои же тезисы.

Тех самых программистов класса "программер стоит почти столько же" как раз и нельзя включать на серьёзных ролях в команду, которая занимается разработкой на C++. Только в роли подмастерья, под зоркий контроль старших (и заметно более жадных по деньгам) товарищей.

Должный уровень профессионализма как раз и позволяет
(а) минимизировать те самые SIGSEGV
(б) за разумное время (а с современными инструментами - и вовсе быстро) разруливать порчу стеков
(в) писать стабильно работающие MT-программы и успешно устранять просочившиеся-таки ошибки.

А так - отдельные "талантливые" программисты и на Java нередко умудряются прострелить себе ногу, успешно устроив трудноуловимую утечку памяти (еще хуже - других, внешних ресурсов) в большой программе или написав алгоритм, который начинает зверски тормозить при мало-мальском увеличении объёмов данных. В каждой среде - свои сложности и пути их преодоления.

Date: 2014-09-29 09:12 pm (UTC)
From: [identity profile] dz.livejournal.com
Профессионализм программера - удачные алгоритмы. Борьба с segv - глупость. Не надо бороться с тем, про что можно просто забыть. Что до утечек памяти в Яве, то - 1) это ещё надо умудриться, 2) тот, кто устроил утечку на Яве в Си устроит полный кабздец.

Я уж молчу про дизайн структур данных. После полугода работы с GC ручное управление памятью вызывает ступор не меньший, чем предложение пересесть с авто на лошадь.

Date: 2014-09-09 07:13 am (UTC)
From: [identity profile] tzirechnoy.livejournal.com
Зато использование только managed ЯП на 100-рублёвом MCU -- это идиотизм.

Date: 2014-09-09 08:53 am (UTC)
From: [identity profile] dz.livejournal.com
В сим-картах (!!) давно Java работает, так что - было бы желание.

Date: 2014-09-11 07:34 am (UTC)
From: [identity profile] tzirechnoy.livejournal.com
Так у меня там тожэ схема запихана. Для прототипирования и кусков кода, которым не важна производительность.

Что не отменяет того, что более половины кода -- ассэмблер. Как, в общем, и на SIM-картах (если считать не только конечные приложэния). При том, что функцыонал приложэний сим-карт -- крайне ограничен.

Date: 2014-09-09 05:58 am (UTC)
From: [identity profile] tzirechnoy.livejournal.com
ЯННП!!!

Какой он undefined, если он указывает на pT? На вполне конкретный pT, который, после записи, будет существенно менять поведение программы, который никогда не вызовет SEGV если просто взять с него int?

И да, напомню всем, что адрес 0 или (void *)0 -- является по стандарту Си неопределённым адресом, не указывающим ни на какой правильный объект, при этом (тожэ по стандарту Си) -- его битовое представление совсем не обязано состоять из нулей.

Т.е. 0 (он жэ NULL, макрос для NULL обычно и определён как (0)) -- это как раз и есть undefined pointer. Независимо от того, нужэн ли программ адрес 0x0.

Date: 2014-09-09 06:53 am (UTC)
From: [identity profile] zinal.livejournal.com
+1.
Такие волшебные платформы, где malloc() или new могут вернуть 0 и это не будет ошибкой - сами по себе не совсем прямые.

Date: 2014-09-09 05:59 am (UTC)
From: [identity profile] kika.livejournal.com
Ну да. А теперь вопрос - а зачем?

Date: 2014-09-09 06:50 am (UTC)
From: [identity profile] zinal.livejournal.com
Не совсем изящно с той точки зрения, что указатели могут копироваться, и копию такого указателя трудно проверить на этот "особенный NULL который не NULL".
Как решение описанной проблемы IMHO можно завести глобальную переменную, а затем макрос NULL сделать равным взятию указателя от такой переменной. Тогда немалая часть кода заработает автоматически, кроме, естественно, старого доброго "void *ptr = 0;" ;)

Date: 2014-09-09 08:57 am (UTC)
From: [identity profile] jsn.livejournal.com
В самом деле, объясните мне, откуда в этом тексте слово "undefined"? What exactly is "not" "defined" there? Я такой код писал пару раз в жизни, вот последний, кажется: https://gist.github.com/jsn/491302, в районе check_stack(). Very well-defined and useful value.

Date: 2014-09-09 08:59 am (UTC)
From: [identity profile] vm-lj.livejournal.com
http://stackoverflow.com/questions/1282295/what-exactly-is-nullptr
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.

Date: 2014-09-09 07:39 pm (UTC)
From: [identity profile] sporadic-man.livejournal.com
> a pointer with an"undefined" value, which would work on a platform where 0x0 is a valid address for data

но зачем.

Date: 2014-09-09 07:48 pm (UTC)
From: [identity profile] evolver.livejournal.com
Какие занудные у тебя друзья! :)

Date: 2014-09-11 07:46 am (UTC)
From: [identity profile] kagand.livejournal.com
Почему-то обсуждение напомнило во что:
- Какой кат купить?
- Купи каяк!
:)

Date: 2014-09-09 09:03 pm (UTC)
From: [identity profile] rblaze.livejournal.com
А потом мы делает pT1 = pT и опа, pT1 уже валидный.

Fundamentals of this sort не надо учить. Это не fundamentals, а очень злое колдунство, изучать которое надо не студентам, а суровым бородатым чернокнижникам, которым себя уже не жалко.Способы открывания портала в ад надо прятать от неофитов, они еще не понимают, что там правда неприятно.

Date: 2014-09-12 08:19 pm (UTC)
From: [identity profile] zaitcev.livejournal.com
Вот именно. Лучше просто ~0 использовать если нулевой адрес недоступен (как в ядре на s390).

Date: 2014-09-28 05:39 am (UTC)
From: [identity profile] zinal.livejournal.com
+1.
Это "злое колдунство", кстати, прекрасно выводится из основ, коим действительно должны учить студентов.

Profile

tobotras: (Default)
tobotras

December 2024

S M T W T F S
123 4567
891011121314
15161718192021
22232425262728
293031    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Feb. 13th, 2026 08:56 pm
Powered by Dreamwidth Studios