Comments 217
malloc принимает количество байт и возвращает нулевой указатель
malloc возвращает указатель на void. void — это не NULL
Как много людей забывают что язык — лишь инструмент, не стоит использовать С++ потому что ты его любишь — используй там где есть от этого выгода, не стоит становиться евангелистами — вера штука опасная, знания — универсальны. Автор статьи (не перевода) был евангелистом С++, потом уверовал в новых богов и вуаля — статья готова, старые идолы повержены.
Ну относительно веры все очень сложно. Недостатки, которые приводит автор, у языка действительно есть. Как и есть недостатки у Хаскеля. Просто в данный момент времени человек предпочитает Хаскель, поэтому поет оды ему и говорит о проблемах плюсов. Раньше оды пелись С++, после Хаскеля придет время чего-то еще…
А чем больше статей, тем лучше — читать их иногда интересно. Они и помогают лучше выбрать инструмент, а не верить в силу какой-то одной технологии.
А чем больше статей, тем лучше — читать их иногда интересно. Они и помогают лучше выбрать инструмент, а не верить в силу какой-то одной технологии.
Некорректное сравнение — у С++ есть очень большой недостаток, причем с момента его появления ,- непрозрачное управление памятью.
Мне кажется, что недостатки есть абсолютно у всего, в том числе и у языков программирования. Подозреваю, что Хаскель, который столь сильно восхваляет автор статьи, тоже ими обладает.
Не хочу спорить с адептом плюсов. Но скажу, что для своих задач я очень давно отказался от С++. Если уж все таки без него не обойтись, то пишу безо всяких плюсов на чистом Си. А, если некоторым нравится есть кактус, то это их выбор. Отладка большой программы написанной на С++ — это занятие не для слабонервных.
Не, я не адепт С++. Я как раз за адекватный выбор инструментов, а не за принципиальную веру в технологию или принципиальный же отказ от нее.
UFO just landed and posted this here
по мне так отладка большой программы на С сложнее, с часто использующимся void*, куда запихивают все подряд, и забавными утечками памяти
Проблема утечек памяти легко решается использованием отладочных версий функций выделения и освобождения памяти, логирующих все эти действия с указанием, кто, когда, сколько выделил и освободил.
я имею в виду большие программы, с большим количеством ветвлений, где не так просто пройти по ним всем и все отследить
Отладочные версии malloc и free — с этим согласен. Но как вы собираетесь легко логировать действия с указателями?
в проектах изначально использую макросы вида #define X_alloc malloc, #define X_free free
X — какое нибудь сокращение для проекта например.
потом, если надо отладить утечку, заменяются макросы на #define X_alloc(size) LoggingAlloc(size, __FILE__, __LINE__)
пишется простенькая LoggingAlloc, логирующая например в файл переданные параметры в удобочитаемом или машинноанализируемом виде. далее утечка отлавливается без особых проблем.
это к слову позволяет и двойные free отладить.
можно еще сделать определение макросов X_alloc и X_free в зависимости от какой либо переменной препроцессора, например
#define DEBUG_ALLOC
X — какое нибудь сокращение для проекта например.
потом, если надо отладить утечку, заменяются макросы на #define X_alloc(size) LoggingAlloc(size, __FILE__, __LINE__)
пишется простенькая LoggingAlloc, логирующая например в файл переданные параметры в удобочитаемом или машинноанализируемом виде. далее утечка отлавливается без особых проблем.
это к слову позволяет и двойные free отладить.
можно еще сделать определение макросов X_alloc и X_free в зависимости от какой либо переменной препроцессора, например
#define DEBUG_ALLOC
Это все легко позволяет найти место в коде, в котором была выделена память. А также позволяет выяснить, что память по каким-либо причниам не была удалена, либо, как вы написали, отловить повторное удаление. Но такой подход все равно не позволяет легко выяснить, почему память не была освобождена. А это самая нужная информация. Естесственно, речь идет о действительно больших программах. Если где-то еще будет задействован механизм подсчета ссылок, то выяснить, кто удерживает ссылку еще сложнее.
На моей практике, если знать, где память была выделена — можно уже многое сказать о том, почему она не была освобождена.
Согласитесь, это намного лучше, чем знать, что у вас «утекло» столько то памяти.
Согласитесь, это намного лучше, чем знать, что у вас «утекло» столько то памяти.
UFO just landed and posted this here
Полностью согласен. C++ пора на пенсию. Большинство из идиом программирования C++ не унаследованных от C не работают.
Но, к сожалению, пока нет альтернативы.
Но, к сожалению, пока нет альтернативы.
Альтернативы есть. Никто же не заставляет писать именно на плюсах, если это так тяжело и неудобно?:)
UFO just landed and posted this here
>Полностью согласен. C++ пора на пенсию.
Я это слышал и 5 лет назад, и 10 лет назад, и даже 15 лет назад. Поговаривают, что и 20 лет назад говорили то же самое. Да, точно: как только Java появилась и стала более-менее распространенной, так сразу C++ начали отправлять на пенсию. Да, вы не ослышались: когда значительная часть хабраюзеров еще ходила в детский сад, уже тогда начали отправлять С++ на пенсию. А он по какой-то невероятной причине все не уходит и не уходит, несмотря на все заявления доморощенных «икспертов». Странно, не правда ли?
Я это слышал и 5 лет назад, и 10 лет назад, и даже 15 лет назад. Поговаривают, что и 20 лет назад говорили то же самое. Да, точно: как только Java появилась и стала более-менее распространенной, так сразу C++ начали отправлять на пенсию. Да, вы не ослышались: когда значительная часть хабраюзеров еще ходила в детский сад, уже тогда начали отправлять С++ на пенсию. А он по какой-то невероятной причине все не уходит и не уходит, несмотря на все заявления доморощенных «икспертов». Странно, не правда ли?
Совсем не странно. C++ — лучший вариант в соотношении скорость разработки/скорость исполнения с приоритетом скорости исполнения. В игровой (AAA) индустрии ему нет равных.
UFO just landed and posted this here
Майнкрафт сделан на яве, например
И именно поэтому там всё очень удачно в плане модификаций и плагинов.
У каждого языка есть свои недостатки и плюсы, для разных целей — разный инструмент.
Удачно только лишь потому, что удалось декомпилировать его. Если сравнить написание модификаций на движке Source и Minecraft, второе — сущий ад. Конечно, отчасти потому, что api никакого нет. Но на плюсах «копошить» внутренности куда удобнее и практичнее. Я уж не говорю, какую нагрузку они дают на и так очень тяжелую игру.
Выставьте Render distance хотя бы в 512 блоков, тогда узнаете как майнкрафт не тормозит. И это после обработки OptiFine-ом.
Я считаю, что язык С++ и вся его философия находятся в прямом конфликте с требованиями функционального программирования.
Насколько я понимаю (помню Страуструпа), философия С++ заключается в том, чтобы позволять выбирать лучшие абстракции для каждой конкнретной предметной области. Для многопоточности да, сишные структуры и указатели на них — не лучший выбор. Но в прицнипе никто не мешает, а некоторые даже рекомендуют, при программировании многопоточных вещей использовать неизменяемые данные, копировать их вместо перемещения или передачи ссылки и избавлять функции от сторонних эффектов, насколько это возможно. В тексте справедливо замечено, что по умолчанию это не гарантируется, но философия С++ как раз в том и состоит, чтобы навязывать программисту как можно меньше умолчаний. Стрелять себе в ногу — это почетное право, а не обязанность.
Конечно, идея смотреть на функциональные языки в контексте многопоточности — здравая. Могу подтвердить, правда, не Хаскеллем, а Эрлангом — после полугода программирования исключительно на нем, код на плюсах тоже стал намного более функциональнообразным со всеми приятными бонусами в виде потокобезопасности и читаемости.
Но ведь и объектная парадигма возникла не на пустом месте. Да и императивный код с циклами тоже может быть весьма полезным, особенно там, где побочные эффекты неизбежны и порядок вычисления критически важен. С++ позволяет не только порождать сложноотлаживаемые ошибки в промышленном количестве, но и работу работать, как ни странно, причем на всех уровнях. От функциональных блоков на контроллерах нижнего уровня на АЭС, до казуальных квестов под айпад с андройдом, причем одновременно.
При этом С++ движется и в сторону параллельного программирования, хотя и не всегда так здорово, как хотелось бы. PPL и AMP, например, как раз и предназначены для задействования многоядерных платформ и GPU. Все мы там будем. Хотя и не сразу. Хотя, наверное, и не все.
Да, у Мейерса, кажется, было целое правило про мультипарадигменность С++ — каждый волен выбирать свой подход.
UFO just landed and posted this here
Неловко из-за своего незнания, но что используется в ФП в качестве эквивалента циклам?
Например, map. Функция, которая применяет функцию к каждому элементу чего-либо. Как for-each. Разницы на самом деле немного. В Питоне, например, циклы сделаны в императивном стиле, но фактически работают над ленивыми списками.
Ну и классика — рекурсия. В теле функции проверям: если счетчик дошел до конца, ничего не делаем, если нет — делаем что-то, запускаем саму же функцию с подвинутым счетчиком. Сперва выглядит неуклюже, но это дело привычки.
Ну и классика — рекурсия. В теле функции проверям: если счетчик дошел до конца, ничего не делаем, если нет — делаем что-то, запускаем саму же функцию с подвинутым счетчиком. Сперва выглядит неуклюже, но это дело привычки.
Нужно наконец заняться выпиливанием deprecated хлама и делать это активнее. Хотя это же и Си касается. А заодно и выкинуть из железа и осей кучу deprecated мусора надо бы. Но видимо нам еще долго придется жить с рудиментами.
А замены типа Rust или D пока еще слишком нестабильны, причем вторые уже слишком долго не могут устаканиться и веры в них уже почти не осталось.
Справедливости ради, после даже беглого изучения Хаскеля начинаешь куда лучше писать и читать С++ шаблоны.
А замены типа Rust или D пока еще слишком нестабильны, причем вторые уже слишком долго не могут устаканиться и веры в них уже почти не осталось.
Справедливости ради, после даже беглого изучения Хаскеля начинаешь куда лучше писать и читать С++ шаблоны.
deprecated хлам часто выпиливают в отдельных конторах — жесткие codestyle'ы, ревью плохого кода просто не проходит. А из языка все рудименты убрать не так-то просто: обратная совместимость тянет такие идеи ко дну.
Так ведь сколько этих рудиментов в процессорах осталось к примеру.
Обратная совместимость это то, что не нужно новым проектам написанным с нуля, и большинству библиотек относительно свежих версий.
Интересно, а никому в голову не приходило выпилить все рудименты и просто назвать язык по новому? Какой-нибудь CleanC++, тогда и с обратной совместимостью проблем нет, так как это, по сути, новый язык. И с каждым апдейтом С++ добавлять фичи и в CleanC++
А кому он нужен будет?
Как писали выше, для «отдельных контор», да и коммент пользователя Gorthauer87 плюсанули уже 9 раз, значит это как бы востребовано. Ну и, лично мне кажется, что язык, из которого вырежут всё устаревшее, станет только лучше, разве не так?
Сделать его бинарно совместимым на уровне объектных файлов с «обычным» C++. По сути это флаг компилятора, выключающий вещи, которые нельзя использовать в исходнике.
Насчет замены — посмотри на Golang. Мне после Go на C и C++ возвращаться не хочется. ;-)
Rust — интересный (и похож во многом на Go), но пока еще не готов для продакшн.
Rust — интересный (и похож во многом на Go), но пока еще не готов для продакшн.
UFO just landed and posted this here
Ну, отлично. А, допустим, мне нужно выделить память для пяти объектов, размеры которых мне известны заранее? И, допустим, объекты нужны все целиком, или ни один из них.
Я могу сделать malloc на сумму размера, и выделить потом указатели на эту штуку. Да, не очень красиво. Но мы экономим память, у нас нет дифрагментации кучи, и, может, даже из-за кэширования чуть чуть выигрываем в производительности.
А теперь мне надо сделать пять раз new?
Кроме этого, я работаю под SSE, и мне надо сделать aligned malloc. Ладно, скажут, расслабся — у нас всегда aligned malloc, это, правда, в стандарте не прописано — но вы просто поверьте, а поймёте потом?
Или по той или иной причине хочу выровнять malloc на ширину кэш линии. Ну, межпроцессорные взаимодействия, то, сё.
Я могу сделать malloc на сумму размера, и выделить потом указатели на эту штуку. Да, не очень красиво. Но мы экономим память, у нас нет дифрагментации кучи, и, может, даже из-за кэширования чуть чуть выигрываем в производительности.
А теперь мне надо сделать пять раз new?
Кроме этого, я работаю под SSE, и мне надо сделать aligned malloc. Ладно, скажут, расслабся — у нас всегда aligned malloc, это, правда, в стандарте не прописано — но вы просто поверьте, а поймёте потом?
Или по той или иной причине хочу выровнять malloc на ширину кэш линии. Ну, межпроцессорные взаимодействия, то, сё.
UFO just landed and posted this here
Почему? У меня есть пять запросов на выделение памяти с каким-то размерами. Почему это будет работать не хуже, чем один такой запрос?
Это может определить только компилятор: ооо, мы тут выделяем все вместе, а тут освобождаем все вместе, давайте заменим это на одну операцию.
Это может определить только компилятор: ооо, мы тут выделяем все вместе, а тут освобождаем все вместе, давайте заменим это на одну операцию.
UFO just landed and posted this here
Т.е. код
Убьёт всё, как только вылезем за адресное пространство процесса? Атлично-атлично!
int* b[1000]
for(int i=0; i<1000; i++)
{
int* a = new int[256*1024*1024+i];
b[i] = new int;
// do something
free(a)
}
Убьёт всё, как только вылезем за адресное пространство процесса? Атлично-атлично!
Вообще-то для этого есть массивы. Один new для массива из 5 объектов сделает все, что нужно, учитывая выравнивание и без фрагментации.
Да лучше просто вектор объявить. А все выделения памяти, распараллеливание и т.д. автоматом уйдут на сторону стандартной библиотеки.
Хорошая иллюстрация неправильного использования возможностей С++.
Вектор это массив позволяющий динамически изменять размер. В условиях было фиксированное количество объектов, то есть вектор тут, во-первых, явный оверхед, а, во-вторых, прекрасный шанс выстрелить себе в ногу, изменив таки его размер, что может вызвать перевыделение массива, и обратившись к объекту по старому указателю.
Вектор это массив позволяющий динамически изменять размер. В условиях было фиксированное количество объектов, то есть вектор тут, во-первых, явный оверхед, а, во-вторых, прекрасный шанс выстрелить себе в ногу, изменив таки его размер, что может вызвать перевыделение массива, и обратившись к объекту по старому указателю.
Хорошая иллюстрация не самого вдумчивого чтения тз.
В условиях сказано, что _размер_ объектов заранее известен. Их количество тоже упомянуто, но про неизменность этого числа не сказано ничего! Это во-первых.
А во-вторых — какое «обратившись по старому указателю»? Тут «выстрел в ногу», а точнее «заряжание ружья» произойдёт ранее, а именно в тот момент, когда вместо итератора вдруг (откуда?) всплывёт указатель.
А что касается изначальной задачи — размещение (где-то) нужного количества элементов — то она как раз будет выполнена. И детали этого процесса могут оказаться гораздо сложнее, чем банальный new или даже malloc
(доводилось работать с реализацией, где вектор держал небольшой буфер на несколько десятков байт прямо у себя, а для большего вообще сразу лез в систему, выделяя себе страницу с помощью апишного VirtualAlloc. И, надо сказать, обгонял при этом и new и даже malloc)
В условиях сказано, что _размер_ объектов заранее известен. Их количество тоже упомянуто, но про неизменность этого числа не сказано ничего! Это во-первых.
А во-вторых — какое «обратившись по старому указателю»? Тут «выстрел в ногу», а точнее «заряжание ружья» произойдёт ранее, а именно в тот момент, когда вместо итератора вдруг (откуда?) всплывёт указатель.
А что касается изначальной задачи — размещение (где-то) нужного количества элементов — то она как раз будет выполнена. И детали этого процесса могут оказаться гораздо сложнее, чем банальный new или даже malloc
(доводилось работать с реализацией, где вектор держал небольшой буфер на несколько десятков байт прямо у себя, а для большего вообще сразу лез в систему, выделяя себе страницу с помощью апишного VirtualAlloc. И, надо сказать, обгонял при этом и new и даже malloc)
> Хорошая иллюстрация не самого вдумчивого чтения тз.
> В условиях сказано, что _размер_ объектов заранее известен. Их количество
> тоже упомянуто, но про неизменность этого числа не сказано ничего!
Это следует из дальнейшего описания. Смысл поста в том, что если понадобилось несколько (допустим 5) однотипных объектов, то вместо пяти вызовов new выгоднее один раз вызвать malloc на все пять, создать указатели (база+смещение) на них и работать с каждым из них по отдельности. Никаких итераторов не предполагается, так как это просто отдельные пять объектов.
> Я могу сделать malloc на сумму размера, и выделить потом указатели на эту штуку.
Так вот, выделение массива из 5 объектов решает ту же задачу, избавляя от низкоуровневой возни с malloc, выравниванием и т.д.
При этом вектор эту задачу не решает или решает плохо. Как я и писал, если не изменять размер — оверхед, если изменять — повисшие указатели стреляют по ногам.
> В условиях сказано, что _размер_ объектов заранее известен. Их количество
> тоже упомянуто, но про неизменность этого числа не сказано ничего!
Это следует из дальнейшего описания. Смысл поста в том, что если понадобилось несколько (допустим 5) однотипных объектов, то вместо пяти вызовов new выгоднее один раз вызвать malloc на все пять, создать указатели (база+смещение) на них и работать с каждым из них по отдельности. Никаких итераторов не предполагается, так как это просто отдельные пять объектов.
> Я могу сделать malloc на сумму размера, и выделить потом указатели на эту штуку.
Так вот, выделение массива из 5 объектов решает ту же задачу, избавляя от низкоуровневой возни с malloc, выравниванием и т.д.
При этом вектор эту задачу не решает или решает плохо. Как я и писал, если не изменять размер — оверхед, если изменять — повисшие указатели стреляют по ногам.
Каждое увеличение и уменьшение счетчика требует блокировки! Эта блокировка обычна реализуется с помощью атомарных переменных, но есть еще и мьютексы! Не позволяйте себя обмануть: доступ к атомарным переменным обходится дорого.
Что, простите?
UFO just landed and posted this here
Я бы еще пропустил утверждение, что атомарные операции на int'е — это дорогая операция (это говорит апологет GC, муахаха). Но при чем тут мьютекс?!
Извините конечно, но очень уж стремно выглядит перевод (?) race как «рейс»
В русском язык мне не известен адекватный перевод термина «data race». Мне привычен разговорный вариант, который часто используется в программистских кругах (или я часто его слышу) — «рейс», его и использовал. И да: вы не первый, кто мне указывает на «корявый» перевод этого термина, но я все же настою на своем варианте.
Мне казалось, вполне устоялся перевод как: «гонки данных», «состояние гонки».
«Состояние гонки» — это всё же race condition, немного другое то есть.
«Гонки данных» — скорее уж, гонки за данными.
Singerofthefall предложил еще и термины «конкуренция данных» или «конкуренция потоков», но мне почему-то всё это не нравится. Возможно, дело привычки.
«Гонки данных» — скорее уж, гонки за данными.
Singerofthefall предложил еще и термины «конкуренция данных» или «конкуренция потоков», но мне почему-то всё это не нравится. Возможно, дело привычки.
Как вариант — коллизия данных?
Просто «гонки». Отлично подходит для всех случаев в статье. Рейс режет глаз.
Хотя бы «рэйс».
C++ монструеет, из него пытаются сделать швейцарский нож на все случаи жизни, при этом теряется главная киллер-фича: эффективная компиляция. Не нужен ещё один скриптовый язык, ещё один функциональный, ещё один многопоточный. Нужен язык для (1) эффективной компиляции (2) сложных архитектурных решений.
Многопоточность — вещь конечно же нужная, но не в виде же костылей! Через несколько лет в десктопах будут стопицот-ядерные камни, и программисты свихнутся распараллеливать на них в мьютексной парадигме, потому что мьютексы (и семафоры) — это тупиковая модель. Откройте для себя Erlang с message-парадигмой, почувствуйте разницу!
И не понял упрека shared_ptr на счет релиза дерева ссылок — раньше это приходилось делать «ручками» явно, теперь это делает shared_ptr. Главное — момент сборки детерминирован самим программистом, а не размазан на «когда нибудь» как в Java GC.
Оставьте плюсам — плюсово, а последние достижения языкознания и компиляторостроения примените к перспективному D.
Многопоточность — вещь конечно же нужная, но не в виде же костылей! Через несколько лет в десктопах будут стопицот-ядерные камни, и программисты свихнутся распараллеливать на них в мьютексной парадигме, потому что мьютексы (и семафоры) — это тупиковая модель. Откройте для себя Erlang с message-парадигмой, почувствуйте разницу!
И не понял упрека shared_ptr на счет релиза дерева ссылок — раньше это приходилось делать «ручками» явно, теперь это делает shared_ptr. Главное — момент сборки детерминирован самим программистом, а не размазан на «когда нибудь» как в Java GC.
Оставьте плюсам — плюсово, а последние достижения языкознания и компиляторостроения примените к перспективному D.
UFO just landed and posted this here
Главное — момент сборки детерминирован самим программистом, а не размазан на «когда нибудь» как в Java GC.Вот в этом и есть ваша ошибка
//management thread
std::shared_ptr<int> ptr;
//worker thread
std::weak_ptr<int> wp = ptr;
std::shared_ptr<int> ptr2 = wp.lock();
Вы можете предполагать (по логике), что ptr должен (долго) удаляться в management thread, и это нормально. Но worker thread не должен тормозиться на удалении ptr. Однако, на самом деле, если management thread завершится до освобождения ptr2, указатель будет (долго) удаляться в worker thread.
Согласен, но по тексту статьи — обход дерева при освобождении shared_ptr упоминался именно в контексте управления памятью/ресурсами. Про shared_ptr в многопоточности автор потом отдельно упомянул, что вы «обретаете большие неприятности», что опять же подверждает мой посыл — поддержка многопоточности в плюсах идет не туда.
Фееричная статья. Шикарная и провоцирующая аналогия вначале, детальный разнос в тексте и слегка предраспологающее к холиварам заключение :)
Замены назревают сами собой, так что не Хаскеллем единым. Для ориентированности на работу с concurrency языкам не обязательно быть функциональными, равно как и для удобства разработки больших проектов, язык не обязательно должен быть классическим ООП-языком.
Из самых зрелых, мощных и с хорошей кармой, пока что ИМХО это Golang — у него очень низкий порог входа из-за большой схожести с С. И после Go возвращаться на C/C++ уже не хочется.
На горизонте еще маячит Rust — близко не знаком, но выглядит очень симпатично.
Замены назревают сами собой, так что не Хаскеллем единым. Для ориентированности на работу с concurrency языкам не обязательно быть функциональными, равно как и для удобства разработки больших проектов, язык не обязательно должен быть классическим ООП-языком.
Из самых зрелых, мощных и с хорошей кармой, пока что ИМХО это Golang — у него очень низкий порог входа из-за большой схожести с С. И после Go возвращаться на C/C++ уже не хочется.
На горизонте еще маячит Rust — близко не знаком, но выглядит очень симпатично.
Я, конечно, не знаю, но так тоже никто уже не пишет на С++
Автор несколько устарел, отсюда и делает неправильные выводы. Правильно писать так:
Более того, Snd тоже неправильно реализован. Там тоже надо использовать умные указатели. Т.к. unique_ptr не использует атомарные операции, то также неправильный вывод о том, что будут проблемы в многопоточных средах.
Snd * snd = new Snd (10);
...
delete snd;
Автор несколько устарел, отсюда и делает неправильные выводы. Правильно писать так:
std::unique_ptr<Snd> snd(new Snd(10));
Более того, Snd тоже неправильно реализован. Там тоже надо использовать умные указатели. Т.к. unique_ptr не использует атомарные операции, то также неправильный вывод о том, что будут проблемы в многопоточных средах.
Каждое увеличение и уменьшение счетчика требует блокировки! Эта блокировка обычна реализуется с помощью атомарных переменных, но есть еще и мьютексы! Не позволяйте себя обмануть: доступ к атомарным переменным обходится дорого.Кручу, верчу, обмануть хочу. Сначала говорится про блокировки, потом про атомарность, потом про мьютексы и опять блокировки. Так это, нужны блокировки для счетчиков или нет? Тумана много напустили. И да, обмануть мы себя не позволим: при отсутствии большой конкуренции к атомарным счетчикам такая операция стоит очень дешево. И не надо лохматить бабушку!
Т.к. unique_ptr не использует атомарные операции, то также неправильный вывод о том, что будут проблемы в многопоточных средах.Как использовать unique_ptr в многопоточных средах?
По разному. Можно — используя атомарные конструкции, можно через мьютексы. Тут стоит обратить внимание не на то, что надо об этом думать, а о том, что автор статьи утверждает, что «доступ к атомарным переменным обходится дорого», поэтому (это уже от меня), дескать, shared_ptr не стоит использовать. Я же говорю, что можно использовать, во-первых, unique_ptr, во-вторых, можно использовать мьютексы, и даже нужно там, где они необходимы.
Автор также говорит про D, типа там есть чистые функции и константные объекты, поэтому есть некие гарантии. Однако, мне не очень понятно, как на D можно работать, на пример, с глобальными контейнерами типа hash_map со всеми ихними константностями и чистыми функциями. Кто-нибудь мне это объяснит? Более того, на С++ тоже можно творить чудеса, см. Полезные идиомы многопоточности С++. В ней я описал, как можно использовать объекты без всяких локов из разных потоках.
Поэтому пафоса автора статья я категорически не разделяю. Указанные примеры кода говорят о том, что автор не знает языка (или знает на достаточно примитивном уровне), и лишь «красиво» треплет языком по делу и без обо всем.
Да, язык С++ не без изъяна, он тяжел для обучения и достаточно громоздок. Но тем не менее, его рано списывать со счетов. Тем более, используя феерические аргументы.
Автор также говорит про D, типа там есть чистые функции и константные объекты, поэтому есть некие гарантии. Однако, мне не очень понятно, как на D можно работать, на пример, с глобальными контейнерами типа hash_map со всеми ихними константностями и чистыми функциями. Кто-нибудь мне это объяснит? Более того, на С++ тоже можно творить чудеса, см. Полезные идиомы многопоточности С++. В ней я описал, как можно использовать объекты без всяких локов из разных потоках.
Поэтому пафоса автора статья я категорически не разделяю. Указанные примеры кода говорят о том, что автор не знает языка (или знает на достаточно примитивном уровне), и лишь «красиво» треплет языком по делу и без обо всем.
Да, язык С++ не без изъяна, он тяжел для обучения и достаточно громоздок. Но тем не менее, его рано списывать со счетов. Тем более, используя феерические аргументы.
Кстати говоря у Вас в статье есть место с дедлоком из коробки.
… Использовать ножи на кухне — это вообще неправильно! Речь даже не о том, что ты можешь порезаться — я верю, что после должного тщательного обучения настоящий профессионал сможет достаточно безопасно приготовить бутерброд. Ведь оставленный на столе нож может привести как к травме (порежется кто-то другой, недостаточно опытный или подготовленный), но и преступлению — оставленные без присмотра ножи могут быть использованы злоумышленниками! А прцесс заточки ножей? Сложность и опасность его неоспоримы. И это в то время, когда любой человек совершенно спокойно может купить порционные продукты — в гигиеничной индивидуальной упаковке, не требующие нарезки! Да, есть стейк без ножа очень неудобно, но ведь прогресс дал нам мясорубки, а котлетки ничуть не менее вкусны и куда более современны, чем эти дикарские стейки! Зачем пытаться как-то совершенствовать безнадежно устаревшую концепцию, придумывая ножи из керамики, самозатачивающиеся, одноразовые ножи из пластика и т. п.? Ведь очевидно, что человечество в ближайшем будущем перейдет на прогрессивное питание полужидкой пастой из тюбиков! Заметьте, что эта передовая технология успешно опробована в космосе, где нет места эти артефактам каменного века — ножам!
UFO just landed and posted this here
Не могу с вами согласиться, увы. С++ — это именно обычный стальной нож. Достаточно опасный, но при этом универсальный и крайне полезный инструмент даже на самой современной кухне. А так — да, полно всяких кухонных комбайнов, блендеров и прочих ломтерезок, конечно.
UFO just landed and posted this here
Автор статьи исходит из ложной предпосылки, что malloc/free или new/delete — это абсолютное зло. А на самом деле это просто возможность порезаться.
Ну нет задачи исключить любую потенциальную угрозу от ножа — иначе им резать же не получится.
Ну нет задачи исключить любую потенциальную угрозу от ножа — иначе им резать же не получится.
На сой взгляд не совсем точная аналогия. Обычный стально нож это C. А потом решили его улучшить и чтобы не терять совместимость, сделали у ножа второе лезвие — получится обоюдоострый. Новое лизкие — C++, старое — C. Резать можно и тем и тем, можно даже чередовать.
Потом изначальный нож стал развиваться дальше потихоньку, но на новом старое лезвие заморозило свое развитие.
С новым еще интереснее. Подумали, что не удобно им резать неторые продукты. Да и порезаться можно… В итоге каждая версия стандарта добавляет на этом лезвии новый участок с хитрой формой и заточкой, при этом старась не строгать уже имеющиеся — люди же уже привыкли ими резать.
И резать таким ножом становится все сложнее. Даже для распространенных продуктов имеется не одно лезвие, а несколько. Причем часть из которых объявлено устаревшими, но они все еще острые и о них можно порезаться.
В общем инструкция к ножу уже перевалила за 100 страниц, и чтобы его освоить уже нужно годичные курсы закончить(просто чтобы не резаться по 5 раз в день), притом что нож позиционируется как массовый и продается на каждом углу.
Потом изначальный нож стал развиваться дальше потихоньку, но на новом старое лезвие заморозило свое развитие.
С новым еще интереснее. Подумали, что не удобно им резать неторые продукты. Да и порезаться можно… В итоге каждая версия стандарта добавляет на этом лезвии новый участок с хитрой формой и заточкой, при этом старась не строгать уже имеющиеся — люди же уже привыкли ими резать.
И резать таким ножом становится все сложнее. Даже для распространенных продуктов имеется не одно лезвие, а несколько. Причем часть из которых объявлено устаревшими, но они все еще острые и о них можно порезаться.
В общем инструкция к ножу уже перевалила за 100 страниц, и чтобы его освоить уже нужно годичные курсы закончить(просто чтобы не резаться по 5 раз в день), притом что нож позиционируется как массовый и продается на каждом углу.
UFO just landed and posted this here
Я считаю, что язык С++ и вся его философия находятся в прямом конфликте с требованиями функционального программирования.— конечно, ведь С++ не функциональный язык
устаревших парадигм программирования— устаревших парадигм не бывает
Вы считаете ручное управление памятью и потоками в С/С++ недостатками? По-моему, это как раз и является сутью и одновременно мощью С/С++. Всё, что можно сделать на других языках программирования можно сделать эффективнее на С, поскольку С — это практически взаимно однозначное соответствие ассемблеру, а какими бы не были эти ваши языки, исполняются они не на этих ваших квантовых компьютерах, а на вполне обычных процессорах.
А если кто-то не умеет программировать на С/С++, то это его проблемы.
UFO just landed and posted this here
Пока компиляторы ваших Java и Haskell пишутся на С, то и говорить не о чем.
UFO just landed and posted this here
Быстрота Haskell обеспечена тем, что программисты С реализовали своё управление памятью, свою многопоточность для решения конкретной задачи. Иначе бы ваш Haskell загнулся бы и работал бы со скоростью runhaskell.
UFO just landed and posted this here
Речь идёт о JVM. Если бы JAVA исполняла JAVA, то всё бы, вообще, загнулось и не работало.
UFO just landed and posted this here
Почему же тогда JIT пишут всегда только на С? Правильно, тут требуется работа с памятью напрямую, на что эти ваши языки не способны. Вообще, все языки написаны на C/C++ (иначе выходит колоссальный ущерб производительности). Даже сам С/С++ написан на себе же. Поэтому — это единственный замкнутый и нормальный язык программирования.
К тому же С — это и есть единственный истинно платформонезависимый язык, ибо первое, что реализуется на любой платформе — это компилятор С, а за ним уже всякие ОС и т.д.
UFO just landed and posted this here
Языков среднего уровня всего две штуки — это С и С++.
Вообще, все языки написаны на C/C++ (иначе выходит колоссальный ущерб производительности).
Господи, что за бред?
Про Модулу, например, не слышали?
Или про другие низкоуровневые языки?
На С пишут, потому что он появился одним из первых и на нем был написан Unix, который получил широкое распространение. С++ стал развитием этого языка и потому тоже стал широко распространенным.
Но это не означает, что это лучшие языки программирования.
Как пример, Java тоже получил широкую популярность в Enterprise среде, а PHP в web-разработке. Но оба этих языка страдают кучей врожденных проблем, которые потом решались путем создания новых языков (Python, Ruby, Scala и прочие).
Также и С/С++ имеют врожденные проблемы, которые, как ни парадоксально, делают их одним из худших выборов для того же системного программирования. Например, очень легкомысленная система типов в языке.
Отсюда при использовании С/С++ возникает куча правил, как стоит и как не стоит писать, которые построены после десятков лет дебаггинга неуловимых багов.
Куча правил, стандартов, условностей, из-за тупо устаревшего концептульано языка, который пытаются возродить новыми стандартами, в то время как правильнее переходить на или разрабатывать более современные низкоуровневые языке (по аналогии того, как, например, была создана Scala, как ответ на несовершенство и медленное развитие Java)
Пока компиляторы ваших Java и Haskell пишутся на С
Почти весь компилятор Haskell написан на (literate) haskell: https://github.com/ghc/ghc. Сишного кода там довольно мало. Тем не менее, используются некоторые динамические библиотеки, написанные на C, вроде libgmp
UFO just landed and posted this here
Я тут же сразу вспоминаю Minecraft и Battlefield 2. В Battlefield 2 почему-то я на своём компе играть могу, а в Minecraft нет…
UFO just landed and posted this here
Просто более-менее крупный проект писать на только одном языке — недальновидно. Я лично для себя нашел идеальную связку: Java для управляющего высокоуровневого кода — манипулирование объектами бизнес-логики, пользовательский интерфейс, машины состояний, то есть то, что Java хорошо умеет, для чего она и делалась. Если между двумя командами проходит более одной миллисекунды машинного времени (я утрирую, конечно), производительность не важна.
А для низкоуровневых алгоритмических задач типа обработки изображений, «перепахивания» крупных массивов данных, рисования графики на OpenGL — язык Си. Да-да, даже не C++. Я использую компилятор C++, чтобы вместо неуклюжих malloc и free иметь new и delete, а также задействовать исключения. А функции вызываются из Java через JNI. Крупные данные хранятся в обычной памяти, всякая разномастная мелочь типа состояний объектов — в Java-памяти.
Вот такой «гибрид». Всем рекомендую. При использовании gcc toolchain и Eclipse с установленными плагинами JDT и CDT можно даже сквозную отладку осуществлять. Главное достоинство — производительность кода на Си в «острых» местах и удобство Java с ее сборщиком мусора и шикарным отладчиком — во всех остальных.
Если бы, например, Minecraft не использовал LWGL для отрисовки всего и вся, а имел бы собственный GL-биндинг на Си, вы бы не отличили производительность
А для низкоуровневых алгоритмических задач типа обработки изображений, «перепахивания» крупных массивов данных, рисования графики на OpenGL — язык Си. Да-да, даже не C++. Я использую компилятор C++, чтобы вместо неуклюжих malloc и free иметь new и delete, а также задействовать исключения. А функции вызываются из Java через JNI. Крупные данные хранятся в обычной памяти, всякая разномастная мелочь типа состояний объектов — в Java-памяти.
Вот такой «гибрид». Всем рекомендую. При использовании gcc toolchain и Eclipse с установленными плагинами JDT и CDT можно даже сквозную отладку осуществлять. Главное достоинство — производительность кода на Си в «острых» местах и удобство Java с ее сборщиком мусора и шикарным отладчиком — во всех остальных.
Если бы, например, Minecraft не использовал LWGL для отрисовки всего и вся, а имел бы собственный GL-биндинг на Си, вы бы не отличили производительность
UFO just landed and posted this here
>Ибо кому, как не программисту, лучше знать, когда область памяти больше не нужна и ее стоит очистить?
Зависит от программиста. Бывают такие, к которым лучше приставить няньку в виде GC. И их, к сожалению, слишком много.
Зависит от программиста. Бывают такие, к которым лучше приставить няньку в виде GC. И их, к сожалению, слишком много.
Это не программисты, а быдлокодеры
UFO just landed and posted this here
Улыбнуло :) Вы так говорите, как будто злые быдлокодеры захватили власть в IT и диктуют всем свои условия :)
Хотите я вам озвучу логику менеджмента софтверной компании?
Конечные пользователи не страдают. Конечные пользователи задают этот тренд, молчаливо покупая и используя говнософт.
Хотите я вам озвучу логику менеджмента софтверной компании?
Я лучше найму 10 джавакодеров, которые понятия не имеют, что, как и когда удаляется, но они за 3 месяца напишут продукт, который я начну продавать и заработаю деньги, чем я за те же деньги найму 5 мега-сишников, которые просто ппц какие умные, но писать тот же самый продукт они будут год (просто потому, что во-первых их вдвое меньше, а во-вторых разработка на джаве идет реально быстрее, чем на Си), а за это время мой продукт уже будет на хрен никому не нужен, т.к. конкурент выпустит свой аналог через 3 месяца и захватит весь рынок, в результате чего мне придется закрыться к чертям и идти собирать бутылки.
Конечные пользователи не страдают. Конечные пользователи задают этот тренд, молчаливо покупая и используя говнософт.
Перефразируя предыдущего оратора чуть общее: в любой области, где человечество что-либо создаёт, от живописи до производства автомобилей, сперва появляются несколько гениев, которые намечают основной тренд, потом творчество обретает популярность, становится выгодным и появляется рынок труда для «ремесленников», причем выигрывают не те, кто делает лучше, а те, кто лучше продаёт готовый продукт.
Так что «пипл хавает». Зарабатывают больше всех середнячки, нашедшие баланс между качеством и ценой. И это — закон природы, на который непродуктивно обижаться.
Утешает только то, что количество гениев по абсолютному значению не меняется. И хотя их слышно хуже, когда вокруг такой «гвалт», они продолжают создавать шедевры. Надо лишь уметь их видеть.
Так что «пипл хавает». Зарабатывают больше всех середнячки, нашедшие баланс между качеством и ценой. И это — закон природы, на который непродуктивно обижаться.
Утешает только то, что количество гениев по абсолютному значению не меняется. И хотя их слышно хуже, когда вокруг такой «гвалт», они продолжают создавать шедевры. Надо лишь уметь их видеть.
На самом деле Erlang, Haskell и вообще функциональное программирвоание — отличные штуки. Особено когда все бесконечно параллелится и у вас есть кластер, на котором можно все это дело запускать и быстро добавить туда еще машин, когда понадобится.
Но иногда бывает необходимо просто что-то быстро посчитать. Или оказывается, что ваше приложение должно работать в условиях ограниченных ресурсов. Или ваш алгоритм нельзя распараллелить. Или разбиение на несколько машин приведет к тому, что пересылка данных между ними сотрет все преимущества параллельного выполнения.
Реализовать же пересылку событий между потоками, как в Erlang, в С++ не представляет какой-то проблемы.
Про мьютексы и атомарные переменные — вообще не серьезно. Автор, наверное, думает, что функциональные языки используют внутре себя какую-нибудь магию для организации подсчета ссылок и синхронизации между потоками, но уж никак не примитивы ОС и атомарные операции. Или логика такая — раз я мьютекса не вижу — занчит его нет?
Но иногда бывает необходимо просто что-то быстро посчитать. Или оказывается, что ваше приложение должно работать в условиях ограниченных ресурсов. Или ваш алгоритм нельзя распараллелить. Или разбиение на несколько машин приведет к тому, что пересылка данных между ними сотрет все преимущества параллельного выполнения.
Реализовать же пересылку событий между потоками, как в Erlang, в С++ не представляет какой-то проблемы.
Про мьютексы и атомарные переменные — вообще не серьезно. Автор, наверное, думает, что функциональные языки используют внутре себя какую-нибудь магию для организации подсчета ссылок и синхронизации между потоками, но уж никак не примитивы ОС и атомарные операции. Или логика такая — раз я мьютекса не вижу — занчит его нет?
Логика такая, что
1. multi-threading approach — Semaphores, Threads, Shared Memory
2. message passing approach — Queues, Messages, Processes
3. data flow concurrency
4. software transnational memory
Это все разные модели parallel/concurrency вычислений. Операционные системы поддерживают только первый вид. Остальные модели реализуются посредством библиотек и собственных планировщиков легковесных потоков со своими стеками работающих в контексте одного потока ОС.
Чисто логически представьте себе что в одном 32-битном потоке Эрланга работает 1 000 000 процессов, откуда там столько примитивов ОС.
1. multi-threading approach — Semaphores, Threads, Shared Memory
2. message passing approach — Queues, Messages, Processes
3. data flow concurrency
4. software transnational memory
Это все разные модели parallel/concurrency вычислений. Операционные системы поддерживают только первый вид. Остальные модели реализуются посредством библиотек и собственных планировщиков легковесных потоков со своими стеками работающих в контексте одного потока ОС.
Чисто логически представьте себе что в одном 32-битном потоке Эрланга работает 1 000 000 процессов, откуда там столько примитивов ОС.
Внутри одного потока ОС синхронизаиця, конечно, не нужна. Но если мы хотим использовать более одного потока ОС, да и вообще взаимодействоать с внешним миром, то нашему планировщику придется использовать какие-то механизмы синхронизации. Сколько бы библиотек мы не использовали, в итоге все равно все сводится к примитивам ОС или атомарным переменным. И как только мы хотим перейти через границу своего уютненького потока, нам их приходится использовать.
Как обычно бывает в таких случаях, войну между императивными и функциональными языками выиграет язык, который умудрится помирить обе парадигмы внутри себя.
За примером подобной победы далеко ходить не нужно. Обсуждаемый здесь C++ в своё время победил в споре между C и объектно-ориентированным Smalltalk-ом, включив в себя ООП вида «объект-тип данных», который отлично уживался со стилем программирования на тогдашних императивных языках, популярен до сих пор и, по сути, мирит между две парадигмы между собой.
За примером подобной победы далеко ходить не нужно. Обсуждаемый здесь C++ в своё время победил в споре между C и объектно-ориентированным Smalltalk-ом, включив в себя ООП вида «объект-тип данных», который отлично уживался со стилем программирования на тогдашних императивных языках, популярен до сих пор и, по сути, мирит между две парадигмы между собой.
Так есть же языки, которые на это претендуют. Ruby, например, или F#.
Сузим круг. Язык должен иметь C-образный синтаксис, чтобы 80% разработчиков, пишущие на C/C++/Java/Javascript не меняли своих эстетических предпочтений (то есть, например, не F#, а C# хотя бы) и, кроме того, он должен быть независимым, то есть иметь лёгкую (хотя бы как stdlib/stdc++) стандартную библиотеку, не тянуть за собой виртуальную машину и по производительности результата соперничать с Си.
Я бы сказал, язык, похожий на C# (но с более развитой функциональной семантикой) с компилятором, написанным на основе LLVM (как вариант).
Я бы сказал, язык, похожий на C# (но с более развитой функциональной семантикой) с компилятором, написанным на основе LLVM (как вариант).
Проблема в том, что С-подобный синтаксис не очень-то подходит для программирования в функицональном стиле. Некоторых конструкций просто нет в С стиле (паттерн матчинг, гуарды), дургие имеют зубодробительный синтаксис (оперирование функциями высших порядков, частичное применение, каррирование)
Я думаю, что проблема еще глубже. Разглядывание программ на функциональных языках (писать на них пока не умею, только читать пытаюсь немного) привело меня к мысли, что обычная, привычная нам запись в виде последовательного текста вообще для них не годится. Удобнее бы выглядела графическая блок-схема. Причем такие языки уже есть — навскидку два самых популярных — LabView для математики и SynthMaker для оперирования со звуком (создание VST и VSTi). При этом ничто не мешает добавлять в функциональную блок-схему «островки» императивного кода, который, в свою очередь, лучше выглядит в виде текста.
И, кстати, посмотрев на то, как с кодом и связями работают современные IDE (я в данном случае имею в виду, например, графические связи в XCode 4), можно представить себе, к чему всё идет…
И, кстати, посмотрев на то, как с кодом и связями работают современные IDE (я в данном случае имею в виду, например, графические связи в XCode 4), можно представить себе, к чему всё идет…
Инфраструктура (системы контроля версий, например) заточены под текстовые исходники.
Можно сохранять диаграммы в XML, но (судя по тому, как это сделано в MS Reporting Services и Analysis Services), глазами быстро понять суть изменения по diff-файлу очень сложно.
Можно сохранять диаграммы в XML, но (судя по тому, как это сделано в MS Reporting Services и Analysis Services), глазами быстро понять суть изменения по diff-файлу очень сложно.
Вопрос привычки. По чистому diff-файлу понять изменения тоже непросто — нужна удобная программа визуализации. А то, что структурированные данные мозг лучше принимает, чем колонку текста или цифр — общеизвестный факт. И первые шаги уже делаются — например все среды разработки сейчас поддерживают автоматическую и удобную для человека индентацию.
diff в случае графического языка выглядит чуть иначе. Вот как это выглядит в LabVIEW в простейшем случае:
Код мы храним в MS SourceSafe, при просмотре различий вызывается специальная утилита. Мержить такой код тоже можно (но нам это очень редко приходится делать).
Код мы храним в MS SourceSafe, при просмотре различий вызывается специальная утилита. Мержить такой код тоже можно (но нам это очень редко приходится делать).
Уточню, о чём я хотел сказать. Очевидное визуальное изменение (врезка в середину диаграммы нового объекта со сдвигом всей нижележащей диаграммы вниз) повлечёт большую цепь изменений в сериализованном в файл представлении (если там координаты объектов сохранены). Конечно, современные VCS съедят мегабайтные диффы и не подавятся, а внешние тулзы визуализируют разницу двух версий, но как-то это неправильно. Если кто-то вставит в диаграмму объект в другом месте и тоже со сдвигом остатка вниз, мержить это будет просто невозможно.
Там (в LabVIEW) всё чуть сложнее. Есть понятие Data Flow («потока данных»), и если диаграмма просто раздвигается для вставки новых элементов — это считается «косметическим» изменением и не приводит к изменению Data Flow. Если два разработчика вставили по куску кода (не конфликтующего), раздвинув оригинальную диаграмму в разных направлениях, то такой код прекрасно мержится, так как вначале меняется Data Flow, а потом результирующая диаграмма раздвигается в обоих направлениях (ну при больших изменениях, возможно придётся ручками кое-что подвигать). Могу скриншот сделать, если интересно. В настоящее время, конечно неудобно то, что в системе контроля версий файлы хранятся как двоичные и об их содержимом SCC ни сном ни духом. Сериализация как таковая в LabVIEW вообще не предусмотрена, соответственно диффов тоже нет (ну разве что визуально показывается что там куда мержится — примерно как на скриншоте выше). Вообще формат исходников LabVIEW — суть внутренний закрытый формат (что конечно, не есть хорошо). Возможно в будущем появятся похожие средства графической разработки с открытым форматом и соответственным образом заточенные под них системы контроля версий.
Понятно, но у такого подхода есть и минус: если пользователь переместит элементы, чтобы придать схеме красоты (код же равняют отступами), то система это не сохранит.
Сохранит — эта информация тоже ведь хранится в исходном файле. Но для системы контроля версий, конечно не будет разницы — просто косметическое изменение сделано или принципиальное — в настоящее время система видит лишь изменившийся двоичный файл. О деталях изменений знают только внешние тулзы сравнения и мержинга. Вы выше абсолютно верно написали, что системы контроля версий заточены под текстовые исходники — я просто хотел показать как diff отображается в графическом виде, и что такой код можно мержить. Я так думаю, что в далёком (очень далёком) будущем ситуация изменится и графические функциональные средства разработки постепенно вытеснят классические текстовые, но это произойдет реально нескоро.
с компилятором, написанным на основе LLVMСм. mono. В наличии LLVM-бакэнд rjljutythfwbb и возможность жить без JIT.
Смотрел. Года два я очень пристально на него смотрел, так как C# (но без обвязки Microsoft) — мой любимый язык. Но mono — очень тяжел, к тому же имеет такую лицензию, что встраивать его в свои приложения можно только за деньги.
Эм? Встраивать только за деньги? Весь код реализации фреймворка под лицензией MIT, libmono под LGPL, линкуйтесь динамически и всё будет лицензионно чисто и бесплатно. С тяжеловесностью можно поспорить: если тащить за собой только нужное, то вполне можно уложиться в 5-10 мегабайт в запакованном виде, память же в рантайме оно кушает довольно аккуратно.
malloc принимает количество байт и возвращает указатель на void, который вам надо кастить во что-то более удобное — придумать худшее API для управления памяти тяжело
Кажется, автору не стоит позориться незнанием C. В чистом C любой указатель кастится к void*, и void* неявно кастится к любому указателю:
char *string = malloc(len); /* no errors and no warnings in C */
void *ptr = string; /* no errors, no warnings in both C and C++ */
Зачем использовать malloc/free, когда файл исходника имеет расширение cpp для меня большая загадка, разве что кроме случая, когда пишется плюсовый wrapper для сишной библиотеки.
указатели — это зло.
И тут я понял, что весь пост — это такая шутка юмора, расслабился и пошел по своим делам.
Бьерн Страустроуп подчеркивает, насколько важна обратная совместимость для С++.
Умный мужик между прочим. Кому нужен SuperDuperLanguage, для которого нет библиотек (бинарная совместимость с C, в т. ч. в виде костыля extern «C») и ежегодно выходят все новые и новые версии, которые каждый раз на 20% круче и на 80% несовместимы, вынуждая вас либо переписывать код, который работает, либо сидеть на старой версии языка (превед, python 3!)
Вот моя история:
эволюция с использования стандартных библиотек типа core data в сторону примитивов NSArray, NSObject основанных на С у меня совпала с эволюцией apple в сторону C++. Почему так — 85% падений в С++ коде аппла.
Сборка boost под iOS в 2013 году напомнила сборку java applet в году эдак 96м (кто помнит тот в курсе, не вместятся маты в сообщение)
Видимо С++ дает возможность программисту в его части проекта наделать херни и при этом дает повод его не найти и поругать систему.
Вообще — давайте себе признаемся в том что врядли легко принять — большая часть языков на рынке создано не для того чтобы был happy coding а для того чтобы была работа для всех, а не только для людей которые ПОНИМАЮТ ЧТО ОНИ ДЕЛАЮТ И КАК ОНО РАБОТАЕТ.
эволюция с использования стандартных библиотек типа core data в сторону примитивов NSArray, NSObject основанных на С у меня совпала с эволюцией apple в сторону C++. Почему так — 85% падений в С++ коде аппла.
Сборка boost под iOS в 2013 году напомнила сборку java applet в году эдак 96м (кто помнит тот в курсе, не вместятся маты в сообщение)
Видимо С++ дает возможность программисту в его части проекта наделать херни и при этом дает повод его не найти и поругать систему.
Вообще — давайте себе признаемся в том что врядли легко принять — большая часть языков на рынке создано не для того чтобы был happy coding а для того чтобы была работа для всех, а не только для людей которые ПОНИМАЮТ ЧТО ОНИ ДЕЛАЮТ И КАК ОНО РАБОТАЕТ.
Нынче модный тренд — ругать С++… Но идеалов нет, и вполне может быть, что некоторые восхваляемые на данный момент языки скоро так же будут поругиваться. Не стоит смотреть однобоко и давать 1001 подтверждение того, что С++ уже так безнадежен.
OCaml лучше С++ со всех сторон.
что некоторые восхваляемые на данный момент языки скоро так же будут поругиваться.
Есть ли языки, которые не ругают с момента выхода их в свет? :)
Как-то в одной конторе был очередной обеденный треп с поругиванием очередного продукта. И было замечание одного коллеги, что есть ПО, которое ругают, а есть, которое не используют.
Зачастую люди даже не пробовали использовать, а уже ругают :)
На эту тему есть замечательный развёрнутый пост: commandcenter.blogspot.co.uk/2011/12/esmereldas-imagination.html
Вот бы ему хороший хабраперевод…
Вот бы ему хороший хабраперевод…
There are only two kinds of languages: the ones people complain about and the ones nobody uses.
Bjarne Stroustrup
— Маамаааа! Этот язык программирования предоставляет мне выбор! Слишком много выбора! Мне страшно, мама! Можно я попишу на Бейсике? (с) :-)
Хотел было откомментить, но пока я лично не увижу написанный на глубокоуважаемом автором Haskell'е проект серьезнее «лабы» (не требую операционную систему или игру, согласен на что-либо уровня firefox / utorent / netbeans либо nginx / redis / mc ) даже в спор вступать не вижу смысла. Лисп тоже отец всех языков, ну и.
P.S: Xmonad не предлагать, это несерьёзно
Автор — Бартош Милевски. Я не знаю, что именно он написал на Haskell, можно посмотреть тут: bartoszmilewski.com/category/haskell/
Видел, как некоторые пользовались en.wikipedia.org/wiki/Darcs
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
зачем минусовать переводчика, если не нравится автор? Такие как вы в свое вермя убивали гонцов с плохими новостями.
UFO just landed and posted this here
ваше несогласие с автором не делает его статью «неадекватным говном».
UFO just landed and posted this here
по-моему, пользуясь вашей аналогией, в статье идет разговор о том, что попыткта сделать универсальную розетку заканчивается постоянными ударами тока, и что как бы пора уже перейти на новый стандарт розеток и прекратить идти на поводу у людей со старым напряжением, но никто этого делать не хочет и все продолжают терпеть удары током.
Кидайтесь в меня камнями, но я вот чего не понимаю:
каждый раз когда я раздумываю или гуглю на тему «а почему нет компилятора питона в машинный код», поднимаются тонны контраргументов типа «сложные типы данных», «хитрые особенности языка».
Но вот вопрос: а в современном C++ этих особенностей меньше, что-ли? Все эти smart pointers, темплейты, головоломные оптимизации, итд итп?
каждый раз когда я раздумываю или гуглю на тему «а почему нет компилятора питона в машинный код», поднимаются тонны контраргументов типа «сложные типы данных», «хитрые особенности языка».
Но вот вопрос: а в современном C++ этих особенностей меньше, что-ли? Все эти smart pointers, темплейты, головоломные оптимизации, итд итп?
Это две совсем разные вещи. В python «сложные типы данных» и «хитрые особенности языка» относятся к сложности их реализации в компилируемом языке, а в C++, к сожалению, к использованию, а реализация у них несколько упрощена, как раз ценой усложнения использования. Один плюс — они работают и компилируются в native code.
Для статической компиляции в машинный код необходимо провести статический анализ программы.
Для динамических языков, вроде питона, это в общем случае проделать невозможно — грубо говоря, невозможно заранее определить, что должен делать код, не выполнив его.
За примерами далеко ходить не надо:
Для динамических языков, вроде питона, это в общем случае проделать невозможно — грубо говоря, невозможно заранее определить, что должен делать код, не выполнив его.
За примерами далеко ходить не надо:
eval()
в одиночку сводит любую возможность компиляции в машинный код на нет.Люди, которые кричат о «кривости» С/С++ и отправляют его на пенсию, наверно, забывают, что ВСЕ! современные распространенные (не берем во внимание какие-то специфические) операционные системы написаны не на Haskel, не на Java, не на Python или Ruby. Что почти ВСЕ компиляторы/интерпретаторы/трансляторы/виртуальные машины для других языков написаны тоже на С/С++!.. А не чем написаны большинство СУБД? А не чем написаны сервисы/серверы для тех операционных систем, которые написаны на С++?
Просто очень мало нормальных языков для системного программирования существует, вот и пользуются все попсовым С++.
Тем не менее, даже для системного программирования С++ далеко не идеален из-за своего сишного наследия.
Тем не менее, даже для системного программирования С++ далеко не идеален из-за своего сишного наследия.
вот и пользуются все попсовым С++.
Тем не менее, даже для системного программирования С++ далеко не идеален из-за своего сишного наследия.
а какие альтернативы?
D. Теоретически язык отличный, индустрии всего-то осталось взять, навалиться скопом и дописать уже нормальный компилятор и библиотеки. Поработать плотно лишний месяц или год, зато потом наслаждаться десятилетиями.
Но нет, всем влом, «моя хата с краю», лучше ещё раз помучаюсь с C++.
Но нет, всем влом, «моя хата с краю», лучше ещё раз помучаюсь с C++.
Си может работать на голом железе и сам реализовать все библиотечные функции. А другим языкам нужен runtime, который должен быть над программой. Поэтому оси и драйвера сложнее писать. Нужно минимальное ядро на том же си.
Почти все языки того поколения обходились без Runtime. Паскаль, например. Однако остальные сошли с дистанции. «Голый» Си удобен прежде всего тем, что он — «кроссплатформенный ассемблер». То есть язык настолько туп и близок к железу, насколько это возможно при наличии строгой типизации, циклов, функций и прочих высокоуровневых абстракций.
Си шикарно сочетает в себе самостоятельность, о которой вы написали, легкую читабельность, сравнимую с высокоуровневыми языками, кроссплатформенность и почти ассемблерную мощь.
Си шикарно сочетает в себе самостоятельность, о которой вы написали, легкую читабельность, сравнимую с высокоуровневыми языками, кроссплатформенность и почти ассемблерную мощь.
Нам бы в новом проекте сейчас идеально подошел D. Но отсутствие _нормальной_ нативной библиотеки линейной алгебры заставило рассматривать другие варианты. Выбрали Julia, вроде бы, почти идеально, но уж больно она пока сырая.
Это я к чему, если есть желание, то напишите хорошую библиотеку ЛА для D. Сделаете очень хорошее дело. Если начнете — обещаю подключусь.
Это я к чему, если есть желание, то напишите хорошую библиотеку ЛА для D. Сделаете очень хорошее дело. Если начнете — обещаю подключусь.
А что именно вам нужно от библиотеки ЛА? От предметной области сильно зависит скоуп такой библиотеки. В геймдеве, например, не нужны обобщения векторных произведений, а в деформативном моделировании — суперскалярные операции.
Вообще, я давно хотел попробовать D, ну и с линейной алгеброй немного знаком. Если это кому-то надо, могу попробовать заняться.
Вообще, я давно хотел попробовать D, ну и с линейной алгеброй немного знаком. Если это кому-то надо, могу попробовать заняться.
На самом деле не так много: матрично-векторная арифметика, определитель, норма фробениуса и евклидова, обратная и псевдообратная матрицы, сингулярное разложение. Пока, кажется, только это используем. Может быть, что-то забыл или в будущем что-то еще понадобится.
В Джулии просто целый зоопарк разложений, там писать и писать :-)
Ок, почитаю-поиграюсь с языком, в понедельник определюсь окончательно. Кое-что я уже переписывал на плюсах, питоне и шарпе, — в принципе видение задачи есть. Меня, конечно, смущает, что про D я пока только введение Александреску читал, но с другой стороны не боги горшки обжигают: будет востребовано — будет комьюнити, будет комьюнити — научат как надо.
Ок, почитаю-поиграюсь с языком, в понедельник определюсь окончательно. Кое-что я уже переписывал на плюсах, питоне и шарпе, — в принципе видение задачи есть. Меня, конечно, смущает, что про D я пока только введение Александреску читал, но с другой стороны не боги горшки обжигают: будет востребовано — будет комьюнити, будет комьюнити — научат как надо.
Да, Julia очень хорошая задумка. Только сейчас там баг на баге всплывает. Наверное, и от нее откажемся.
А про D, я так же только эту книгу прочитал, ничего существенного на нем не писал. Но книга и язык впечатлили.
А про D, я так же только эту книгу прочитал, ничего существенного на нем не писал. Но книга и язык впечатлили.
Ну, как-то начал: github.com/akalenuk/la
Julia, на мой взгляд (игрался где-то пол года назад), совсем сырой язык и пока не подходит для реальных проектов. Не страшно его использовать? А вообще задумка у них очень хорошая — простота языка, сравнимая с Matlab/Python, направленность на математические пакеты/векторизацию/параллелизм и скорость, сравнимая с C/C++.
UFO just landed and posted this here
Не смешивайте Си и Си плюс плюс. О Си речи в статье не шло. Си — язык системного программирования, от него никто не ждёт простоты использования или высокой скорости разработки. А вот для разработки ПО для конечного пользователя и удобство, и скорость важны.
Haskell, конечно, хорош, но там много собственных проблем. Space leaks, оптимизация, извечная борьба с ленивостью, сложные для восприятия абстракции. К слову, упомянутая книжка Саймона Марлоу действительно великолепна.
Приходится мириться с тем, что есть ряд задач, в которых требуется максимизация отношения полезные инструкции/киловатт. В мобильных устройствах, к примеру. На том же Going Native 2013 Александреску объяснял, что для фейсбука (где он сейчас работает) повышение производительности даже на несколько процентов — хорошая оптимизация и неплохая экономия. Ради этого они делают страшные и некрасивые вещи вроде собственных таблиц виртуальных функций. Язык, конечно, сложный, но что делать, наследие. Я пришёл к нему после 4 лет промышленной Java, и, если честно, не особо горю желанием возвращаться. Хотя многих вещей не хватает. D&E Страуструпа поясняет, почему всё именно так, как оно есть…
В комментариях видел отсылки к Golang — это действительно отличный и стабильный язык, глоток свежего воздуха в совтверном мире, поросшем слоями абстракций. Многие вещи там сделаны очень правильно, программировать на нём довольно приятно (порой почти также приятно, как на Haskell). Огорчает в основном отсутствие аналога шаблонов, что порой вынуждает писать однообразный код. Причём неизвестно, когда это исправят, и исправят ли вообще.
Недавно узнал про язык Clay, думаю посмотреть на него поближе на досуге. Выглядит многообещающе.
Приходится мириться с тем, что есть ряд задач, в которых требуется максимизация отношения полезные инструкции/киловатт. В мобильных устройствах, к примеру. На том же Going Native 2013 Александреску объяснял, что для фейсбука (где он сейчас работает) повышение производительности даже на несколько процентов — хорошая оптимизация и неплохая экономия. Ради этого они делают страшные и некрасивые вещи вроде собственных таблиц виртуальных функций. Язык, конечно, сложный, но что делать, наследие. Я пришёл к нему после 4 лет промышленной Java, и, если честно, не особо горю желанием возвращаться. Хотя многих вещей не хватает. D&E Страуструпа поясняет, почему всё именно так, как оно есть…
В комментариях видел отсылки к Golang — это действительно отличный и стабильный язык, глоток свежего воздуха в совтверном мире, поросшем слоями абстракций. Многие вещи там сделаны очень правильно, программировать на нём довольно приятно (порой почти также приятно, как на Haskell). Огорчает в основном отсутствие аналога шаблонов, что порой вынуждает писать однообразный код. Причём неизвестно, когда это исправят, и исправят ли вообще.
Недавно узнал про язык Clay, думаю посмотреть на него поближе на досуге. Выглядит многообещающе.
По-моему, Макконнелл в своей книге «Совершенный код» очень мудро посоветовал разрабатывать не на языке, а с использованием языка… и объяснил, что это означает. Очень применимо к данной статье.
Именно поэтому я давно и прочно предпочитаю использовать С вместо С++.
Sign up to leave a comment.
Эдвард руки — С++