?

Log in

Ух ты! - Оживший юзерпик

Sep. 9th, 2014

09:40 am - Ух ты!

Previous Entry Share Next Entry

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:

[User Picture]
From:vitus_wagner
Date:September 9th, 2014 05:47 am (UTC)
(Link)
Вот если бы в С/С++ было принято делать проверку указателя на неопределенность маросом IS_NULL(p), а не сравнением p==NULL....
(Reply) (Thread)
[User Picture]
From:tzirechnoy
Date:September 9th, 2014 05:59 am (UTC)
(Link)
Какая разница?
(Reply) (Parent) (Thread)
[User Picture]
From:vitus_wagner
Date:September 9th, 2014 06:05 am (UTC)
(Link)
Тогда просто переопределив этот макрос можно было перейти от схемы "неопределенный указатель равен нулю" к "неопределенный указатель равен адресу переменной, в которой он хранится".
(Reply) (Parent) (Thread)
[User Picture]
From:zaitcev
Date:September 9th, 2014 10:14 pm (UTC)
(Link)
Сломается после первого присваивания.
(Reply) (Parent) (Thread)
[User Picture]
From:beldmit
Date:September 9th, 2014 12:53 pm (UTC)
(Link)
В стандарте 2011-го года в эту сторону сделали некоторые телодвижения.
(Reply) (Parent) (Thread)
[User Picture]
From:dz
Date:September 9th, 2014 05:52 am (UTC)
(Link)
Люди, которые в 21-м веке жрут с кинжала, должны гордиться порезами морды, я считаю.

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

И, кстати, такое должен ловить статический анализатор. Которых, БЛЯДЬ, для си до сих пор, оказывается, тоже нет.
(Reply) (Thread)
[User Picture]
From:d1f
Date:September 9th, 2014 06:08 am (UTC)
(Link)
Зачем? Не мешайте нам стрелять себе в ногу!
(Reply) (Parent) (Thread)
[User Picture]
From:dz
Date:September 9th, 2014 08:57 am (UTC)
(Link)
Тогда нехер скулить. Свои бешеные пойнтеры нужно нести над головой гордо.

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

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

(Reply) (Parent) (Thread)
From:ostapru
Date:September 10th, 2014 02:00 am (UTC)
(Link)
CLion: http://habrahabr.ru/company/JetBrains/blog/236061/
(Reply) (Parent) (Thread)
[User Picture]
From:dz
Date:September 10th, 2014 03:01 pm (UTC)
(Link)
Спасибо, обязательно посмотрю. Подозреваю, что с исходниками ядра оно не справится, но попытку сделать надо.
(Reply) (Parent) (Thread)
From:ostapru
Date:September 18th, 2014 07:48 pm (UTC)
(Link)
Кстати, в качестве статического анализатора для "це" чем линт не устраивает?

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

И кстати, там есть ссылочка на список статических анализаторов для всего: http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis
(Reply) (Parent) (Thread)
[User Picture]
From:dz
Date:September 21st, 2014 09:44 pm (UTC)
(Link)
Вы видели статик аналайзер inellij Idea? Стоит посмотреть. После этого линт стыдно вообще вспоминать.
(Reply) (Parent) (Thread)
[User Picture]
From:zinal
Date:September 9th, 2014 06:52 am (UTC)
(Link)
Дело вкуса, знаете ли.
У C++ и С есть свои сильные стороны, отнюдь не завязанные на производительность.
По каким-то загадочным причинам ни одного "managed" языка, имеющего аналогичные сильные стороны, в широком применении не появилось. Хотя тот же C++ постепенно двигается в похожем направлении.
(Reply) (Parent) (Thread)
From:vm_lj
Date:September 9th, 2014 08:56 am (UTC)
(Link)
какие именно?
(Reply) (Parent) (Thread)
[User Picture]
From:zinal
Date:September 27th, 2014 05:35 pm (UTC)
(Link)
C++:
1. Возможность выбора между OOP и generic programming.
2. Возможность сочетания одного с другим
3. Возможность явного управления памятью там, где это нужно (во многих случаях это - большое преимущество)
4. Деструкторы вместо финализаторов
5. Полноценное множественное наследование (есть много паттернов, где его применение сильно упрощает жизнь)
5. Возможность доступа к низкоуровневым операциям ОС и аппаратуры

C:
1. Простой и чёткий синтаксис - при соблюдении элементарной гигиены, разумеется
2. Возможность доступа к низкоуровневым операциям ОС и аппаратуры
3. Высокая степень предсказуемости программы, сравнительно простая отладка при использовании современных инструментов
4. Один язык реально для любого окружения - поддерживается действительно везде
(Reply) (Parent) (Thread)
[User Picture]
From:dz
Date:September 9th, 2014 09:05 am (UTC)
(Link)
"Дело вкуса" - это, извините, ответ любителя. Ответ профессионала опирается на стоимость производства и стоимость эксплуатации. Стоимость разработки на старых и новых яп различается на полпорядка. Может быть, у Си и есть сильные стороны, но на стоимости разработки они сказаться не способны.

(Reply) (Parent) (Thread)
[User Picture]
From:zinal
Date:September 27th, 2014 05:41 pm (UTC)
(Link)
Стоимость производства и эксплуатации, извините, в основном определяется стоимостью содержания команды, способной разрабатывать и сопровождать код. Средняя команда, работающая со сложным кодом на C++, стоит заметно дороже аналогичной команды, работающей, например, с Java или новомодной Closure. С этим спорить глупо.

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

И да, 75% реально работающего кода - дрянь, худо-бедно отлаженная толпой идиотов. Увы.
(Reply) (Parent) (Thread)
[User Picture]
From:tobotras
Date:September 27th, 2014 05:44 pm (UTC)
(Link)
Не согласен, буду глупо спорить.

Не согласен, буду глупо спорить.

Согласен :)
(Reply) (Parent) (Thread)
[User Picture]
From:zinal
Date:September 27th, 2014 06:21 pm (UTC)
(Link)
П.1, п.2 - можно поподробнее? Интересно мнение умного человека :)
Глядишь, и сам поумнею.

Кстати, п.2 действительно спорный, отсюда и IMHO ;)
(Reply) (Parent) (Thread)
[User Picture]
From:tobotras
Date:September 27th, 2014 06:41 pm (UTC)
(Link)
Прямо так, без пива? Ну, даже не знаю :)

IMHO: сложная система требует в первом приближении одинаковой квалификации программистов без особенной зависимости от языка/технологии. Сложнее ли типичная система, написанная на плюсах, типичной системы, написанной на Java?
(Reply) (Parent) (Thread)
[User Picture]
From:zinal
Date:September 28th, 2014 05:37 am (UTC)
(Link)
Пиво или там иная рюмка чая в нынешних обстоятельствах вполне организуемы ;)

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

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

Так вот, более высокая смысловая плотность качественного кода на C++ по сравнению с качественным же кодом на Java, в сочетании с немалым количеством способов непреднамеренно выстрелить себе в ногу на C++, реально требует от хорошего C++ программиста заметно более высокой технической квалификации по сравнению с хорошим же программистом на Java.
(Reply) (Parent) (Thread)
[User Picture]
From:dz
Date:September 29th, 2014 03:03 pm (UTC)
(Link)
Смысловая плотность кода - это МИНУС, а не плюс. Это - снижение читаемости.

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

(Reply) (Parent) (Thread)
[User Picture]
From:zinal
Date:September 29th, 2014 04:43 pm (UTC)
(Link)
Смысловая плотность, как некая характеристика, для конкретного программиста, читающего либо пишущего код, имеет комфортный (то бишь наиболее эффективный) именно для данного программиста диапазон.

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

К слову, некоторые другие языки в Java-экосистеме с этим недостатком успешно борются, а некоторые (тот же Closure) его лишены напрочь. Сложный код на Schema/Closure иногда как раз хочется искусственно растянуть - но это хотя бы возможно физически.
(Reply) (Parent) (Thread)
[User Picture]
From:dz
Date:September 29th, 2014 09:18 pm (UTC)
(Link)
Неплотность явы, в основном, сводится к

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

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

всё.

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


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

(Reply) (Parent) (Thread)
[User Picture]
From:zinal
Date:September 29th, 2014 04:53 pm (UTC)
(Link)
Мне не очень хочется что-либо тут доказывать, у каждого есть свой личный немаленький опыт как основа для суждений.
Просто предыдущим текстом вы как раз напрямую подтверждаете мои же тезисы.

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

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

А так - отдельные "талантливые" программисты и на Java нередко умудряются прострелить себе ногу, успешно устроив трудноуловимую утечку памяти (еще хуже - других, внешних ресурсов) в большой программе или написав алгоритм, который начинает зверски тормозить при мало-мальском увеличении объёмов данных. В каждой среде - свои сложности и пути их преодоления.
(Reply) (Parent) (Thread)
[User Picture]
From:dz
Date:September 29th, 2014 09:12 pm (UTC)
(Link)
Профессионализм программера - удачные алгоритмы. Борьба с segv - глупость. Не надо бороться с тем, про что можно просто забыть. Что до утечек памяти в Яве, то - 1) это ещё надо умудриться, 2) тот, кто устроил утечку на Яве в Си устроит полный кабздец.

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

(Reply) (Parent) (Thread)
[User Picture]
From:tzirechnoy
Date:September 9th, 2014 07:13 am (UTC)
(Link)
Зато использование только managed ЯП на 100-рублёвом MCU -- это идиотизм.
(Reply) (Parent) (Thread)
[User Picture]
From:dz
Date:September 9th, 2014 08:53 am (UTC)
(Link)
В сим-картах (!!) давно Java работает, так что - было бы желание.
(Reply) (Parent) (Thread)
[User Picture]
From:tzirechnoy
Date:September 11th, 2014 07:34 am (UTC)
(Link)
Так у меня там тожэ схема запихана. Для прототипирования и кусков кода, которым не важна производительность.

Что не отменяет того, что более половины кода -- ассэмблер. Как, в общем, и на SIM-картах (если считать не только конечные приложэния). При том, что функцыонал приложэний сим-карт -- крайне ограничен.
(Reply) (Parent) (Thread)
[User Picture]
From:tzirechnoy
Date:September 9th, 2014 05:58 am (UTC)
(Link)
ЯННП!!!

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

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

Т.е. 0 (он жэ NULL, макрос для NULL обычно и определён как (0)) -- это как раз и есть undefined pointer. Независимо от того, нужэн ли программ адрес 0x0.
(Reply) (Thread)
[User Picture]
From:zinal
Date:September 9th, 2014 06:53 am (UTC)
(Link)
+1.
Такие волшебные платформы, где malloc() или new могут вернуть 0 и это не будет ошибкой - сами по себе не совсем прямые.
(Reply) (Parent) (Thread)
[User Picture]
From:kika
Date:September 9th, 2014 05:59 am (UTC)
(Link)
Ну да. А теперь вопрос - а зачем?
(Reply) (Thread)
[User Picture]
From:tobotras
Date:September 9th, 2014 06:12 am (UTC)
(Link)
Красивые вещи красивы вне зависимости от бытовой пользы!
(Reply) (Parent) (Thread)
[User Picture]
From:zinal
Date:September 9th, 2014 06:50 am (UTC)
(Link)
Не совсем изящно с той точки зрения, что указатели могут копироваться, и копию такого указателя трудно проверить на этот "особенный NULL который не NULL".
Как решение описанной проблемы IMHO можно завести глобальную переменную, а затем макрос NULL сделать равным взятию указателя от такой переменной. Тогда немалая часть кода заработает автоматически, кроме, естественно, старого доброго "void *ptr = 0;" ;)
(Reply) (Thread)
[User Picture]
From:jsn
Date:September 9th, 2014 08:57 am (UTC)
(Link)
В самом деле, объясните мне, откуда в этом тексте слово "undefined"? What exactly is "not" "defined" there? Я такой код писал пару раз в жизни, вот последний, кажется: https://gist.github.com/jsn/491302, в районе check_stack(). Very well-defined and useful value.
(Reply) (Thread)
From:vm_lj
Date:September 9th, 2014 08:59 am (UTC)
(Link)
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.
(Reply) (Thread)
[User Picture]
From:sporadic_man
Date:September 9th, 2014 07:39 pm (UTC)
(Link)
> a pointer with an"undefined" value, which would work on a platform where 0x0 is a valid address for data

но зачем.
(Reply) (Thread)
[User Picture]
From:evolver
Date:September 9th, 2014 07:48 pm (UTC)
(Link)
Какие занудные у тебя друзья! :)
(Reply) (Thread)
[User Picture]
From:tobotras
Date:September 10th, 2014 03:13 am (UTC)
(Link)
Но любим мы их не за это же :)
(Reply) (Parent) (Thread)
[User Picture]
From:kagand
Date:September 11th, 2014 07:46 am (UTC)
(Link)
Почему-то обсуждение напомнило во что:
- Какой кат купить?
- Купи каяк!
:)
(Reply) (Parent) (Thread)
[User Picture]
From:tobotras
Date:September 11th, 2014 07:50 am (UTC)
(Link)
Ну, так это все сетевые дискуссии так устроены, что ж теперь.
(Reply) (Parent) (Thread)
[User Picture]
From:rblaze
Date:September 9th, 2014 09:03 pm (UTC)
(Link)
А потом мы делает pT1 = pT и опа, pT1 уже валидный.

Fundamentals of this sort не надо учить. Это не fundamentals, а очень злое колдунство, изучать которое надо не студентам, а суровым бородатым чернокнижникам, которым себя уже не жалко.Способы открывания портала в ад надо прятать от неофитов, они еще не понимают, что там правда неприятно.
(Reply) (Thread)
[User Picture]
From:zaitcev
Date:September 12th, 2014 08:19 pm (UTC)
(Link)
Вот именно. Лучше просто ~0 использовать если нулевой адрес недоступен (как в ядре на s390).
(Reply) (Parent) (Thread)
[User Picture]
From:zinal
Date:September 28th, 2014 05:39 am (UTC)
(Link)
+1.
Это "злое колдунство", кстати, прекрасно выводится из основ, коим действительно должны учить студентов.
(Reply) (Parent) (Thread)