Комментарии 393
НЛО прилетело и опубликовало эту надпись здесь
Rust и swift теперь точно сожрут плюсы, тут к гадалке не ходи.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
swift нынче без obj-c рантайма на линуксе работает и есть проект по реализации основных foundation'ов чисто на нём.
НЛО прилетело и опубликовало эту надпись здесь
Мне кажется, что для ui swift удобнее и плюсов и раста. В 3ьей версии обещают интероперабельность с плюсами, а когда-нибудь мы быть может увидим и для rust'а интероперабельность, тем более мне кажется, что это то как раз проще сделать, чем с плюсами.
В 3ьей версии обещают интероперабельность с плюсами
Не обещают. Как раз наоборот — упоминают в разделе out of scope.
НЛО прилетело и опубликовало эту надпись здесь
Не сожрал бы. Он намного медленней...
НЛО прилетело и опубликовало эту надпись здесь
С чего бы это? А может она обновляется 10 раз, а не 30, поэтому и берут С++.
НЛО прилетело и опубликовало эту надпись здесь
Ваш уровень аргументации, напоминает — "я знаю, каратэ, ушу, айкидо, бокс — и ещё много других страшных слов".
Про движки — спасибо, было весело....
Про движки — спасибо, было весело....
НЛО прилетело и опубликовало эту надпись здесь
Правда? Это наверное потому что openGL — это чистый Си, вот так сюрприз…
С++ может нативно использовать Си, предоставляя более совершенную систему контроля типов, при том же быстродействии.
А если вы посмотрите глубже, то представьте себе… процессор выполняет микрокод, для него всё равно на каком языке написан софт — внутри процессора это всё микрокод...
С++ может нативно использовать Си, предоставляя более совершенную систему контроля типов, при том же быстродействии.
А если вы посмотрите глубже, то представьте себе… процессор выполняет микрокод, для него всё равно на каком языке написан софт — внутри процессора это всё микрокод...
Да уж DirectX на столько pure C что аж все его интерфейсы дыбом встают. Спасибо посмеялся.
Вы работаете с драйвером или api? Потому что в DX с шейдерами и девайсом и контекстом и всем остальным я работаю через классы. Апи по физике(коллизии) тоже как бы делается через интерфейсы (PhysiX). И о чудо Unreal С++, Unity С++, Cry C++. Никто не пишет движки на С уже давно, последний из С движков это id Tech 5 (да и то не уверен, 6 версия уже на С++)
Основная работа по растеризации, применении шейдеров лежит на pure C драйвере устройста.
Вы работаете с драйвером или api? Потому что в DX с шейдерами и девайсом и контекстом и всем остальным я работаю через классы. Апи по физике(коллизии) тоже как бы делается через интерфейсы (PhysiX). И о чудо Unreal С++, Unity С++, Cry C++. Никто не пишет движки на С уже давно, последний из С движков это id Tech 5 (да и то не уверен, 6 версия уже на С++)
компилятор языка С++ от интела переписан на С++ уже давно. LLVM — C++, gcc и то на С++ (обрезанный) перевели.
А вы пробовали сами на нём писать какие-либо библиотеки, а не тупо использовать то, что вам выкатила Apple?
НЛО прилетело и опубликовало эту надпись здесь
Т.е. чистые библиотеки вы не писали, зато мнение имеете…
Просто покажите код, который вы писали, или ссылки которые подтверждают ваши аргументы (про движки и т.п.), иначе это просто газификация луж...
Просто покажите код, который вы писали, или ссылки которые подтверждают ваши аргументы (про движки и т.п.), иначе это просто газификация луж...
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Скатились в "Сам дурак" ?
НЛО прилетело и опубликовало эту надпись здесь
- Я привёл список проектов, которые написаны на Си++.
- https://github.com/borisovs
- дискутировать с вами не интересно...
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Chrome. Yandex.Search.
Ошибаетесь, не все. Драйвера — часто при разработке WDM драйверов используется C++. «Рантаймы языков» — .NET CLR и Oracle JVM написаны на C++.
Даже в embedded все чаще используют C++.
Даже в embedded все чаще используют C++.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Свежи предания, да верится с трудом. «Пожирателей» С++ было уже немало, а воз и ныне там. К тому же, с очередными потенциальными «пожирателями» Вы, скорее всего, сильно ошиблись: Rust — это, скорее, замена С, а не С++, а Swift — вообще «местечковый» язык, который вряд ли выйдет за пределе «яблочной» экосистемы. Ни тот, ни другой на замену С++ в принципе и не претендуют. Откушать где-то небольшую нишу, занятую сейчас С++ может и смогут, но сожрать… Я Вас умоляю!
Вы правы, Rust — замена C, и именно по этому он — конкурент C++, который тоже замена C. По субъективным ощущениям, раст — на голову выше плюсов почти по всем направлениям. Это я как заядлый плюсовик заявляю. Если ещё не пробовали на нём писать, то вам непременно стоит это сделать.
P.S. Swift вообще не о то. Зачем он тут вообще? Какое отношение он имеет к области применимости плюсов?
P.S. Swift вообще не о то. Зачем он тут вообще? Какое отношение он имеет к области применимости плюсов?
> Rust — это, скорее, замена С, а не С++
А можно раскрыть мысль? Несколько раз там и сям видел это мнение и не очень его понимаю. Может я слово «замена» в таком контексте как-то не так понимаю, может дело в предметной области, где человек работает, хз.
А можно раскрыть мысль? Несколько раз там и сям видел это мнение и не очень его понимаю. Может я слово «замена» в таком контексте как-то не так понимаю, может дело в предметной области, где человек работает, хз.
C (как и Rust) — языки системного программирования, а С++ — язык программирования общего назначения. То есть в теории, конечно, любой язык можно использовать где угодно, но на практике С++ в прикладном программировании удобнее, чем С, Rust, D, и прочие по списку (по крайней мере, на данный момент времени). Потому что в прикладном программировании на первое место выходит не столько сам язык, сколько различные библиотеки: GUI, графика, сети, то-сё. Так вот язык X сможет заменит С++ только тогда, когда на нём напишут большую часть библиотек, которые сейчас в буквальном смысле заставляют плакать, колоться, но писать на С++. Как только будут сопоставимые по мощи аналоги Qt, VTK, Eigen, и прочих библиотек, которые и держат С++ "на плаву", так сразу С++ может утонуть.
Т.е. вопрос в библиотеках, а не самом языке.
Я тихо надеюсь, что ржавчина сможет себе уютное местечко в игрострое отгрызть у плюсов как раз потому, что при написании игровых движков принято велосипедить совершенно все)
Я тихо надеюсь, что ржавчина сможет себе уютное местечко в игрострое отгрызть у плюсов как раз потому, что при написании игровых движков принято велосипедить совершенно все)
Ну не только в библиотеках, а в инструментарии вообще (библиотеки, среды разработки, статические анализаторы и т.д. и т.п.). В общем и целом дихотомию "взлетит-невзлетит" можно свести к следующему простому правилу. Прямо здесь и сейчас в ограниченный промежуток времени новый язык может взлететь в определённой нише только если он: a) позволяет "из коробки" (желательно даже напрямую, без написания каких-либо "обёрток") пользоваться большой частью уже имеющегося в нише инструментария; либо б) богатый сопутствующий инструментарий в нише практически не нужен, так что накладные расходы на его разработку на новом языке в конечном счёте окупятся простотой дальнешего решения уже самой задачи на этом языке.
И да, я не думаю, что серьёзный игровой движок вам кто-то сейчас на Rust велосипедить будет. Это ж дорого, а потенциальных покупателей можно в итоге и не найти. Не только ведь игровые движки на С++ пишут, но и игры. Тут, вроде как, замкнутый круг: большинство игровых движков пишется на С++, потому что большинство игр пишется на С++, а большинство игр пишется на С++, потому что большинство игровых движков пишется на С++.
Честно говоря, я вообще почти не встречал проектов на C++ в которых бы не велосипедили. Никто не любит левые зависимости, как правило.
Мысль не моя, и я как раз считаю, что Rust — прямой конкурент C++. Просто есть мнение, что Rust сильнее C++ не только в прикладной области, но и в области системного программирования, благодаря чему он также может составить конкуренцию C. Сейчас при написании системных вещей выбор стоит как правило C или C++. Смею надеяться, что в скором времени к кандидатам добавиться и Rust. Хотя, к сожалению, область очень консервативная. Зато серьёзную конкуренцию, как мне кажется, Rust может составить C++ в игрострое.
Rust — это, скорее, замена С, а не С++
Мысль не моя, и я как раз считаю, что Rust — прямой конкурент C++. Просто есть мнение, что Rust сильнее C++ не только в прикладной области, но и в области системного программирования, благодаря чему он также может составить конкуренцию C. Сейчас при написании системных вещей выбор стоит как правило C или C++. Смею надеяться, что в скором времени к кандидатам добавиться и Rust. Хотя, к сожалению, область очень консервативная. Зато серьёзную конкуренцию, как мне кажется, Rust может составить C++ в игрострое.
С++ — не замена С. Чётко очерченная на данный момент ниша С — системное программирование — лишь отчасти пересекается с таковой С++. С++ — язык общего назначения. На нём можно писать и системное, и прикладное ПО, и вот в нише прикладного ПО, которая несоизмеримо больше, С вообще ни разу не конкурент С++. C# да Java там основные конкуренты, ну VB.NET c Python ещё можно упомянуть, плюс в конкретных областях "местечковые конкуренты" (типа Fortran для высоко-производительных вычислений).
По моему, давно пора.
Сходил к гадалке, сказала что С++ проживет еще вечность, а насчет Rust/Swift она не уверена. Сорри.
Той гадалкой был Бьёрн Страуструп.
НЛО прилетело и опубликовало эту надпись здесь
Swift не поддерживается на Windows. И тут можно конечно разводить демагогию что "Windows не нужна", но сейчас, с точки зрения рынка, намного аппетитней, если уж на то пошло, выглядит C#. Он становится все более кросс-платформенным, для него поспеют зрелые тулы (посмотрите например на Project Rider).
Я ничего не имею против Swift, я просмотрел пару курсов на Pluralsight — он мне нравится, но пока Apple тянет одеяло на себя, ничего хорошего не получится.
Я ничего не имею против Swift, я просмотрел пару курсов на Pluralsight — он мне нравится, но пока Apple тянет одеяло на себя, ничего хорошего не получится.
НЛО прилетело и опубликовало эту надпись здесь
У нас есть F# но у нас нет полноценного инструментария для того, чтобы этим F# воспользоваться в полной мере. Основная проблема — это конечно же вывод типов, а также нервозные попытки понять, в какой же точке из 20 строк в твоей фукции компилятор не смог вывести тип и ему нужно дописать hint. Помимо этого, без поддержки инструментария, использование любого ООП (которое потребуется использовать для взаимодействии с .NET framework) превращается в настоящую агонию. Например реализация сложного интерфейса "вслепую" — да вы даже с 5й попытки не напишете правильный код для нужных свойств и функций.
Еще одно крайне неприятное явление это конечно поведение апологетов F#. Если бы эти люди аргументированно вели беседы и отстаивали свой язык — я бы был только за. Но к сожалению фанаты F# не видят у себя в глазу бревна, зато постоянно пытаются предъявлять какие-то претензии к C#. Я вот недавно на конференции общался, показывал им свой код (у меня коммерческое приложение частично на F#, показывал что частичные рекурсивные шаблоны — это безумие, говорил что я уже после месяца работы возвращаюсь в код и в упор не понимаю что тут написано — а мне отвечали что "ну ты не умеешь его (f#) готовить". Блин. Ну ладно.
Еще одно крайне неприятное явление это конечно поведение апологетов F#. Если бы эти люди аргументированно вели беседы и отстаивали свой язык — я бы был только за. Но к сожалению фанаты F# не видят у себя в глазу бревна, зато постоянно пытаются предъявлять какие-то претензии к C#. Я вот недавно на конференции общался, показывал им свой код (у меня коммерческое приложение частично на F#, показывал что частичные рекурсивные шаблоны — это безумие, говорил что я уже после месяца работы возвращаюсь в код и в упор не понимаю что тут написано — а мне отвечали что "ну ты не умеешь его (f#) готовить". Блин. Ну ладно.
НЛО прилетело и опубликовало эту надпись здесь
Да ну вас, где ж тут хейтеры. Swift выглядит как отличный язык, я не спорю. Просто для того чтобы писать на языке, нужно иметь веб-фреймворки, оконные классы, и все такое. На Mac, понятно, все это есть через Cocoa. На Windows ничего этого нет. То есть для бэкенда оно может конечно и подошло бы но, по-хорошему, это куча работы. Что касается "прикрутят", вы плохо знаете Microsoft — они сами добровольно не будут ничего такого делать. Посмотрите на OSX/Linux — есть ли там WPF, например. Его нет, и в ближайшем будущем не планируется. Бизнес-модель MS — это пересадить всех в облако.
есть милый Rust
В D все чего ждут программисты С++ есть очень давно и из коробки. Есть даже возможность компилировать С++ библиотеки с помощью https://github.com/Syniurge/Calypso (правда еще не релиз, но Qt собирает).
Не вижу смысла сейчас начинать новые проекты на С++ если на том же D все будет проще и быстрее. По опыту своих коллег могу сказать, что язык осваивается за пару недель и через месяц можно писать уже писать вполне идиоматический код и не париться с тем, что в С++ будет только через 10-15 лет.
На всякий случай уточню, что я не против Rust т.к. для низкоуровневых вещей он наверно все же крут. Однако более высокоуровневые в разы проще писать на D.
Не вижу смысла сейчас начинать новые проекты на С++ если на том же D все будет проще и быстрее. По опыту своих коллег могу сказать, что язык осваивается за пару недель и через месяц можно писать уже писать вполне идиоматический код и не париться с тем, что в С++ будет только через 10-15 лет.
На всякий случай уточню, что я не против Rust т.к. для низкоуровневых вещей он наверно все же крут. Однако более высокоуровневые в разы проще писать на D.
Что-то он не особо как живым выглядит. Плюсы бы сейчас спасло более частое обновление стандарта, ну раз в полгода понемногу добавлять фичи, к примеру.
D жив, и ещё долго будет оставаться таким. Он малоизвестен, но это ему, скорее + в его положении: высокий уровень стандартизации и централизованность развития в виде двух главных разработчиков. Единственное, что ему не хватает — поддержки со стороны крупных корпораций и отсутствие нормальной IDE, хоть и в этой стороне есть подвижки.
У Go до сих пор нет нормальной IDE и ничего. Мне кажется у D проблема с тем, что он между нишами застрял сейчас. Он не слишком zero cost для системного программирования и при этом не так удобен, как всякие managed языки. В итоге там, где нужна детерменированая работа с памятью и другими ресурсами он не подходит, а где не нужна он проигрывает существующим языкам.
НЛО прилетело и опубликовало эту надпись здесь
Это Go скорее между нишами сидит. На D я могу решать куда больше задач чем на Go, при этом код будет местами значительно короче.
У D есть хорошие шансы понемногу занять нишу С++ т.к. Rust слишком низкоуровневый для ряда задач, а С++ слишком растолстели, чтобы на них можно было писать просто и легко. А других альтернатив нет.
У D есть хорошие шансы понемногу занять нишу С++ т.к. Rust слишком низкоуровневый для ряда задач, а С++ слишком растолстели, чтобы на них можно было писать просто и легко. А других альтернатив нет.
Я пишу на D свои проекты уже несколько лет.
Что для вас zero cost и почему его нет в D? Если оттранслировать C++ код 1 в 1 на D, то при компиляции получится одно и то же.
Детерменированности больше, чем в C++: то, что в C++ UB, в D вполне себе DB. Есть asm statements, которые позволяют писать специфичный код на ассемблере.
При этом сам язык намного мощнее. Возьмём для примера «мама мыла раму» => «раму мыла мама».
Типичное решение на C++(возьмём даже буст для упрощения, попробуете написать на STL?):
boost::copy(«мама мыла раму» | boost::adaptors::tokenized(boost::regex("\w+")) | boost::adaptors::reversed, std::ostream_itertor(std::cout, " "));
Решение на D:
мама мыла раму.split.retro.join().writeln;
Что для вас zero cost и почему его нет в D? Если оттранслировать C++ код 1 в 1 на D, то при компиляции получится одно и то же.
Детерменированности больше, чем в C++: то, что в C++ UB, в D вполне себе DB. Есть asm statements, которые позволяют писать специфичный код на ассемблере.
При этом сам язык намного мощнее. Возьмём для примера «мама мыла раму» => «раму мыла мама».
Типичное решение на C++(возьмём даже буст для упрощения, попробуете написать на STL?):
boost::copy(«мама мыла раму» | boost::adaptors::tokenized(boost::regex("\w+")) | boost::adaptors::reversed, std::ostream_itertor(std::cout, " "));
Решение на D:
мама мыла раму.split.retro.join().writeln;
У меня как не знакомого с D по вашему примеру возник вопрос на тему что в обоих вариантах болше похоже на приемущества/недостатки стандартных библиотек доступных для использования. Т.е. в С++ нужно «сложный» regex использовать, а в D есть готовые удобные методы: «split», «retro», «join».
И только когда я начал читать wiki по D я понял что ваш пример совсем про другое, а именно про UFCS.
На мой взгляд это очень удобная возможность для любого языка.
(комментарий оставил для тех кто как и я не понял изначально сути примера). За пример спасибо.
И только когда я начал читать wiki по D я понял что ваш пример совсем про другое, а именно про UFCS.
На мой взгляд это очень удобная возможность для любого языка.
(комментарий оставил для тех кто как и я не понял изначально сути примера). За пример спасибо.
Garbage Collector ни разу не zero cost. Причём тот самый cost не столько в накладных расходах по тактам и памяти. Сколько в недетерминированности и отсутствии RAII. Как ни прискорбно, все языки с автоматически управляемой памятью делают управление всеми остальными ресурсами полностью ручным.
Да, забыл. Garbage Collector также создаёт проблему таскания рантайма за собой и разборок между рантаймами в случае shared objects. Где язык без сборки мусора может спокойно работать на системном аллокаторе.
D поддерживает RAII, или я вас не так понял?
GC можно вообще отключить и вызывать те же самые malloc/free самостоятельно.
В стандартной библиотеке очень многие алгоритмы не вызывают аллокаций памяти.
Недавно добавили аттрибут nogc, который гарантирует, что блок кода не делает вызовов к GC.
Также появился std.experimental.allocator в котором собрано большое число аллокаторов, как раз для тех, кто не хочет использовать GC. Через пару версий станет стабильным std.allocator.
Я писал множество приложений, начиная от web-сайтов, заканчивая 3D движками на D. Сборщик мусора проблемой никогда не был, наоборот, входит в привычку не заботиться о delete и утечках памяти.
GC можно вообще отключить и вызывать те же самые malloc/free самостоятельно.
В стандартной библиотеке очень многие алгоритмы не вызывают аллокаций памяти.
Недавно добавили аттрибут nogc, который гарантирует, что блок кода не делает вызовов к GC.
Также появился std.experimental.allocator в котором собрано большое число аллокаторов, как раз для тех, кто не хочет использовать GC. Через пару версий станет стабильным std.allocator.
Я писал множество приложений, начиная от web-сайтов, заканчивая 3D движками на D. Сборщик мусора проблемой никогда не был, наоборот, входит в привычку не заботиться о delete и утечках памяти.
ЕМНИП RAII в D делается через scope statement. Это, уж простите, костыль в стиле C# using. Как я сказал, проблема даже не в перформансе — Golang хорошо демонстрирует, что может быть быстрый нативный язык с GC. Проблема в том, что все остальные ресурсы теперь приходится менеджить руками. Или в D появились детерминированные деструкторы?
По поводу рантайма. Если есть несколько динамических либ, каждая из которых собрана со своим рантаймом. Какой рантайм использовать? Особенно если исполняемый файл без рантайма? В общем решаемо, но головной боли добавляет.
По поводу рантайма. Если есть несколько динамических либ, каждая из которых собрана со своим рантаймом. Какой рантайм использовать? Особенно если исполняемый файл без рантайма? В общем решаемо, но головной боли добавляет.
Деструкторы структур в D следуют тем же правилам, что и в C++.
Классы — всегда создаются в куче, поэтому деструктор тоже как и в C++ вызывать нужно руками. А чтобы не вызывать руками — на структурах делается подсчёт ссылок — враппер есть в стандартной библиотеке.
Исполняемый файл без рантайма? Написан на ассемблере, что-ли? Сейчас даже обычное сишное приложение требует свой glibc, иногда той версии, которая отсутствует на хосте.
А в примере с библиотеками: просто линковать статически. Это стандартный вариант сборки библиотек на D.
Классы — всегда создаются в куче, поэтому деструктор тоже как и в C++ вызывать нужно руками. А чтобы не вызывать руками — на структурах делается подсчёт ссылок — враппер есть в стандартной библиотеке.
Исполняемый файл без рантайма? Написан на ассемблере, что-ли? Сейчас даже обычное сишное приложение требует свой glibc, иногда той версии, которая отсутствует на хосте.
А в примере с библиотеками: просто линковать статически. Это стандартный вариант сборки библиотек на D.
В D деструкторы для структур детерминированные — вызываются при выходе из области видимости
Если отключить GC, то отваливается большая часть библиотек, что мягко говоря неприемлемо для разработки. То есть это не аргумент ни разу.
С такой же логикой и в go gc не обязателен, тут люди выкладывали реализацию.
С такой же логикой и в go gc не обязателен, тут люди выкладывали реализацию.
Плагина для JetBrains IDEA и Microsoft VS Code, не считая кучи других, уже недостаточно?
С++ жив за счёт C и всё же довольно мощной оптимизации при компиляции. Но и тут при таком развитии далеко не уедет. А вот какой смысл обновлять стандарт по чуть чуть, проблема в том, что компиляторы далеко не все быстро будут обновляться, да и при этом не все будут постоянно менять версии. Да и в итоге это превратит в кашу еще сильнее, сначала сделают фичу, а потом поймут, что она кривая, что, новую версию фичи добавлять?
А на деле получается, что комитет хочет новые вещи получить в идеальном варианте, при этом именно как правительство, только своей мелкой кучкой. Пока они думают, другие делают, обкатывают на комьюнити и развиваются быстрее. С другой стороны по действиям комитета я могу сказать одно, дьдькам детство вступило в одно место и они хотят поиграться, вот и играют в своей песочнице и им просто наплевать на весь остальной мир, подождет.
А на деле получается, что комитет хочет новые вещи получить в идеальном варианте, при этом именно как правительство, только своей мелкой кучкой. Пока они думают, другие делают, обкатывают на комьюнити и развиваются быстрее. С другой стороны по действиям комитета я могу сказать одно, дьдькам детство вступило в одно место и они хотят поиграться, вот и играют в своей песочнице и им просто наплевать на весь остальной мир, подождет.
Оптимизация C и C++ затруднена, из-за трудности обнаружения алиасов (когда к одной переменной или ячейке памяти можно обратиться несколькими способоми). До сих пор при желании выжать из компилятора максимум используют фортран. Хотя с появлением LLVM можно ожидать эффективной оптимизации и для других языков с ограниченным использованием указателей.
И ведь даже если к след. станадрту введут хотябы одну из ожидаемых фич, то "вау" уже не будет. Будет: "Спасибо конечно, что сделали фичу, которая нам нужна была 5 лет назад". Одно разочарование. Вхождение в стандарт концептов уже почти похоже на выход Half-Life 3.
Главное, чтобы не было похоже на Duke Nukem Forever...
Да чёрт с ними с концептами, где рефлексия? Банальная задача сериализации, возникающая в каждой второй программе на плюсах, без рефлексии нормально не решается.
Ну учитывая что у модулей Stage 6, а у Ranges, Networking, Library Fundamentals 3, and Parallelism 2: Stage 7, есть вероятность что на следующих 2-3 встречах может все решится и появится как минимум TS.
Забыли упомянуть про proposal на 2D Graphics библиотеку на основе Cairo
Забыли упомянуть про proposal на 2D Graphics библиотеку на основе Cairo
НЛО прилетело и опубликовало эту надпись здесь
О Боже… Библиотеку мат. функций они уже в стандарт положили. По моему скромному мнению, С++ не хватает не столько стандартизированных библиотек, сколько стандартизированного (хотя бы де-факто) и лёгкого средства их доставки, сборки на месте и подключения (\me косится в сторону NuGet, NPM, Cargo, Go Get). Тогда можно было бы дорабатывать такие библиотеки независимо от ядра языка. И для простого добавления filesystem не требовался бы комитет.
В NuGet есть поддержка платформы «native», как раз для плюсов. Boost и проч уже там.
В принципе интересно, но неясно, умеет ли NuGet нормально работать за пределами VS. Т.е. служить средством доставки зависимостей для, например, CMake или QMake проекта. Наверное, мне просто хочется аналога Cargo для С++:
Короче, возможность описать для модуля папку с инклюдами, папку с исходниками, список зависимостей — и получить сборку всего этого добра одной командой. Короче, я слишком многого хочу.
- загрузка зависимостей, в т.ч. транзитивная
- транзитивная сборка зависимостей по необходимости
- автоматическое "пробрасывание" Include папок, с возможностью делать публичные и приватные
- мягкое или жёсткое версионирование
- в качестве источников как репозитории артефактов, так и гит-репозитории, УРЛ, локальные папки
Короче, возможность описать для модуля папку с инклюдами, папку с исходниками, список зависимостей — и получить сборку всего этого добра одной командой. Короче, я слишком многого хочу.
Вдогонку. Пока наиболее близок biicode, но нужно разобраться, как его правильно готовить. Вообще же один из основных камней преткновения — отсутствие модулей, из-за чего нельзя нормально изолировать транзитивные зависимости.
Ещё вдогонку для интересующихся. biicode умеет тянуть зависимости только из репозитория. Как я понимаю, такое хранилище можно сделать и локально. Но зависеть от Git репозитория или соседней папки нельзя. Так что мимо.
Зависеть от локальной папки — это прописывать в проектах относительные пути к инклюдам и либам, или что? Не очень понимаю ваш сценарий — как локальные папки представить «пакетами» (кроме как создать в локальной папке, скажем, .nupkg, и руками собрать и толкнуть его в репу). Как публиковать, без репозитория? Как добиться, чтобы у всех эти локальные папки были единообразны? Как версионность поддерживать через локальные папки?
Я вот наоборот стараюсь избавиться от зависимостей с локальными папками, ибо задолбало своей хрупкостью. Исторически у нас как раз повелось лепить зависимости через пути, и теперь хочешь сбилдать один проект — сыграй в угадайку, какие ещё репозитории нужно вытянуть и, главное, по каким папкам их разложить, чтобы начало собираться. Фактически локальные пути заставляют класть все зависимые проекты в пару-другую супер-репозиториев (типа IncludeCommon, Applications и т.п.), вырастающих в огромный ком, и которые всегда нужно клонировать в определённое место и билдать в определённом порядке, и этот порядок передаётся из уст в уста как древнее сказание.
Я вот наоборот стараюсь избавиться от зависимостей с локальными папками, ибо задолбало своей хрупкостью. Исторически у нас как раз повелось лепить зависимости через пути, и теперь хочешь сбилдать один проект — сыграй в угадайку, какие ещё репозитории нужно вытянуть и, главное, по каким папкам их разложить, чтобы начало собираться. Фактически локальные пути заставляют класть все зависимые проекты в пару-другую супер-репозиториев (типа IncludeCommon, Applications и т.п.), вырастающих в огромный ком, и которые всегда нужно клонировать в определённое место и билдать в определённом порядке, и этот порядок передаётся из уст в уста как древнее сказание.
Как раз наоборот — хотелось бы не иметь дела с такими костылями. Хотелось бы иметь систему сборки и доставки зависимостей в одном флаконе. Нечто, аналогичное Cargo. К сожалению, в среде С++ это нереально из-за зоопарка тех самых систем сборки. Поэтому хорошим вариантом была бы система доставки зависимостей и управления сборкой
В общем, мечты, мечты...
- достать "пакет" откуда угодно — хоть из соседней папки, хоть из специального репозитория, хоть из гита
- собрать "пакет" используя его родную систему сборки; результат сборки — бинарники, заголовки и, возможно, какие-либо специфичные конфиг-параметры
- сделать результаты сборки и файлы заголовков видимыми в одной и той же форме, независимо от того, как хаотично они раскиданы в исходном проекте
- корректно "пробрасывать" транзитивные зависимости
В общем, мечты, мечты...
Ситуация еще сложнее, имеется два сценария сборки:
1) "разработка" — здесь желательно иметь как можно более свежий код зависимостей из релиз-веток, коррекция тестов в зависимости от баго-фиксов в них, полная пересборка при выходе мажорных версий…
2) "пост-релиз/установка" — установка чего-то более свежего, вероятно, сломает поведение, но баг-фикс может наоборот исправлять ( тут необходимо различать баг-фикс от минор/мажер версий, чего нет и не предвидится, как результат либо полное ручное управление, либо сборка «на свой страх риск» ), как костыль — хранить все зависимости в установочном пакете.
1) "разработка" — здесь желательно иметь как можно более свежий код зависимостей из релиз-веток, коррекция тестов в зависимости от баго-фиксов в них, полная пересборка при выходе мажорных версий…
2) "пост-релиз/установка" — установка чего-то более свежего, вероятно, сломает поведение, но баг-фикс может наоборот исправлять ( тут необходимо различать баг-фикс от минор/мажер версий, чего нет и не предвидится, как результат либо полное ручное управление, либо сборка «на свой страх риск» ), как костыль — хранить все зависимости в установочном пакете.
Мне кажется, вы пытаетесь возложить на пакетный менеджер несвойственную ему работу по подготовке и сборке файлов для пакета. Ведь «достать исходники откуда угодно, сбилдать чем угодно, упорядочить хаос» — это задача со слишком многими переменными, её должны выполнять майнтайнер пакета и билд-инженер. У package manager-а задача маленькая — получить на вход манифест и файлы на выходе билд-сервера, собрать файлики в кучку согласно описи, заархивировать, проштамповать версию, выдать анонс, хранить пакеты вечно, выдавать пакеты и их зависимости согласно запрошенной версии. А откуда на входе файлики появились — не его забота, для этого есть билд-сервер, тот знает где, что и как брать, как это билдать и как передать сбилданое package manager-у.
Скорее всего да. А ещё я хочу от C++ того, чего в нём не будет ещё лет 5 — нормальной модульности.
Вообще же частенько бывают ситуации, когда поднимать пакетный репозиторий бессмысленно — например требуется всего-то вытаскивать автоматом при сборке парочку бинарных SDK, маленький репозиторий с общим для нескольких продуктов кодом и пару опен-сорс пакетов вроде юнит-тестового фреймворка и логгера.
Вообще же частенько бывают ситуации, когда поднимать пакетный репозиторий бессмысленно — например требуется всего-то вытаскивать автоматом при сборке парочку бинарных SDK, маленький репозиторий с общим для нескольких продуктов кодом и пару опен-сорс пакетов вроде юнит-тестового фреймворка и логгера.
Насколько я понимаю, для NuGet заточен исключительно на MSBuild (он добавляет свои msbuild targets к проектам, а пакеты потом накидывают свои), и на PowerShell (для запуска скриптов), поэтому с СMake/QMake оно дружить не будет. А так вроде всё перечисленное в списке есть, только напрямую из гита конечно ничего качаться не будет, пакеты нужно описать, упаковать и выложить как артефакт, можно в локальную папку, можно на любой NuGet-хост. Никто не мешает класть в пакет исходники — если это нужно для обычной сборки, то клади в обычный пакет, если только для отладки — клади в symbols-пакет. Собственно, boost наглядный пример — там одни лишь исходники.
Ни boost::FS, ни "новая" std::FS до сих пор не поддерживают пути длинее PATH_MAX (260 байт) в Windows, которые самой системой поддерживаются уже почти 10 лет. При этом все красиво и здорово, итераторы и emplace, только вот по факту "новая" функциональность ничуть не лучше какой-нибудь замшелой _mkdir из direct.h, прости рандом.
Ну неправда же. Через UNC всё отлично поддерживается.
Во всяком случае, с boost::filesystem::create_directories и boost::filesystem::copy_file никаких проблем.
В отличие от дотнета, кстати.
Во всяком случае, с boost::filesystem::create_directories и boost::filesystem::copy_file никаких проблем.
В отличие от дотнета, кстати.
Фиг там, извините. Тот факт, что create_directories любезно вызовет CreateDirectoryW, если ей дать полный путь с префиксом \\?\ — это замечательно, конечно, только вот это не поддержка ни разу. Ни канонизацию, ни траверс, ничего с длинным путем нормально сделать нельзя, а соотвествующие тесты даже закомментированы (filesystem\test\path_test.cpp). Т.е. весь траверс и канонизацию предлагается написать самому, и непонятно, зачем тогда вообще такая библиотека.
Мда, и правда.
Я тут совершенно недавно столкнулся с этой проблемой в повершелле (читай — .net), обычный Copy-Item при копировании файлов терял длинные имена и зацикливался на вложенных reparse point-ах.
В итоге переписал его на вызовах winapi и бусте — надо было матчить reparse point-ы, и я решил не полагаться на обёртки. А вот всякие create_directories и copy_file было лениво писать, поэтому #include <boost/filesystem.hpp> и вперед.
Строго говоря, стандартные функции WinAPI тоже упираются в MAX_PATH. С одной стороны — всем страшно ломать совместимость, с другой стороны — для поддержки достаточно тривиальных вызовов приходится городить костыли. В любом случае, странно обвинять в этом
комитет — кто его знает, какие ещё костыли навесят на UNC в следующих релизах. Я бы начал с выпиливания букв, например.
Я тут совершенно недавно столкнулся с этой проблемой в повершелле (читай — .net), обычный Copy-Item при копировании файлов терял длинные имена и зацикливался на вложенных reparse point-ах.
В итоге переписал его на вызовах winapi и бусте — надо было матчить reparse point-ы, и я решил не полагаться на обёртки. А вот всякие create_directories и copy_file было лениво писать, поэтому #include <boost/filesystem.hpp> и вперед.
Строго говоря, стандартные функции WinAPI тоже упираются в MAX_PATH. С одной стороны — всем страшно ломать совместимость, с другой стороны — для поддержки достаточно тривиальных вызовов приходится городить костыли. В любом случае, странно обвинять в этом
комитет — кто его знает, какие ещё костыли навесят на UNC в следующих релизах. Я бы начал с выпиливания букв, например.
Ни boost::FS, ни «новая» std::FS до сих пор не поддерживают пути длинее PATH_MAX (260 байт) в Windows, которые самой системой поддерживаются уже почти 10 лет.
Печаль в том, что исчезающе мало софта поддерживает такие пути, то есть на системном уровне такие пути есть, а на прикладном практически отсутствуют, в том числе в стандартном софте. Та же история с "/" в путях — формально поддерживается, но на деле через раз.
Вроде, в .NET поддержку длинных путей не добавили как раз по этой причине: приложение запросто насоздаёт длинных путей, а остальной софт из-за этого поломается.
Qt их поддерживает из коробки начиная с четвертой версии, поэтому я ими успещно пользовался и был не в курсе проблем с ними. А потом по лицензионным причинам пришлось отвязывать ПО от Qt, и проблемы неожиданно вскрылать так ярко, что теперь, видимо, придется писать свой велосипед по лекалам какого-нибудь FAR Manager'а, код которого открыт и длинные пути который поддерживает в полном объеме.
Ни boost::FS, ни «новая» std::FS до сих пор не поддерживают пути длинее PATH_MAX
Что-о-о-о?!? Серьезно? Это ж каких масштабов fail. Как-то я это совсем упустил, хотя
boot::fs
использовал.А модули все-таки жалко.
Унифицированный синтаксис вызова правильно отменили. Нет, идея отличная, но хотели вывернуть её с ног на голову. D продемонстрировал, что obj.foo(args) должно искать сначала метод, а потом функцию foo(obj, args). А хотели унифицированным сделать foo(obj, args), чтобы он искал метод. Это решает проблему с begin/end, но неудобно для остальных случаев, например статических расширений классов.
По статье не понял, а библиотеку Ranges всё-таки приняли?
По статье не понял, а библиотеку Ranges всё-таки приняли?
Спасибо за интересную статью!
Но если бы стиль был менее быдловатым, читать было бы в разы приятнее.
Но если бы стиль был менее быдловатым, читать было бы в разы приятнее.
С одной стороны соглашусь, но именно из-за стиля статья очень бодро читается. А главное — все понятно.
Пожалуйста.
Нет, не было бы. Академический стиль нуднее в разы, а тут "пока всё им своими словами объяснил — сам уже даже понял".
Нет, не было бы. Академический стиль нуднее в разы, а тут "пока всё им своими словами объяснил — сам уже даже понял".
Ну ок, ёпта
НЛО прилетело и опубликовало эту надпись здесь
Дедуктивный вывод параметров шаблонов
make_pair
так и работал всегда.Но не писать же по отдельной функции на каждый такой шаблон?
А вот странно вообще, что типы функций (шаблонных) выводятся автоматически даже в С++03, а типы конструкторов нет. Так что это скорее не нововведение, а багфикс.
Вот этого-то фикса в C++17 и не будет, как говорится в статье.
А как ты отличишь шаблонный конструктор обычного класса от обычного конструктора шаблонного класса, а если это шаблонный конструктор шаблонного класса?
Такие штуки в плюсах ни один стандарт не исправит уже без скальпеля. А комитет упорно не хочет брать его в руки.
Такие штуки в плюсах ни один стандарт не исправит уже без скальпеля. А комитет упорно не хочет брать его в руки.
А зачем из различать? Если все параметры подставлены, типы их известны, неизвестных типов нет, то не возникает противоречий. Шаблонный ли это конструктор или шаблонный ли это класс — типы известны, ни что не мешает конкретизировать тип.
Такой трюк не пройдёт с шаблонным конструктором шаблонного класса, т.к. у класса и конструктора в шаблонах будут разные наборы типов. Но этого и не требуется.
Такой трюк не пройдёт с шаблонным конструктором шаблонного класса, т.к. у класса и конструктора в шаблонах будут разные наборы типов. Но этого и не требуется.
компилятор C# в случае неоднозначностей просто требует указать тип явно.
Думаю, в случае с С++ не стоит его дальше развивать вообще — слишком много унаследованных проблем. Вместо этого комитету стоило бы создать рабочую группу по разработке принципиально нового языка, базирующегося на классическом си-подобном синтаксисе и включающем все лучшее из С++, C#, D, Go, Rust, Swift и некоторых других языков. И предусмотреть некий стандартизированный механизм взаимодействия кода на двух языках — чтобы можно было переходить постепенно, добавляя в старые проекты на С++ новые файлы с кодом на новом языке.
Вот такое решение было бы пожалуй оптимальным — с одной стороны и "совмесимость" в каком-то виде осталась бы, с другой — можно все написать с нуля, учтя ошибки прошлого.
Вот такое решение было бы пожалуй оптимальным — с одной стороны и "совмесимость" в каком-то виде осталась бы, с другой — можно все написать с нуля, учтя ошибки прошлого.
НЛО прилетело и опубликовало эту надпись здесь
А потом создать ещё один, который включит всё лучшее из перечисленного и того нового, что был создан.
Ну так на то и прогресс чтобы постоянно что-то совершенствовать и учиться на ошибках...
Лет 30 назад предлагали делать язык как систему разноуровневых диалектов, от элементарных низкоуровневых, до высокоуровневых (сейчас бы сказали DSL) специализаций. По своей сути gcc — "коллекция" разных языков и их диалектов, и таковой будет оставаться. А то, что в "c++" нет средств идентификации диалектов, и соответственно средств унифицированной компиляции делает "с++" незаконченной и хрупкой системой, с долгим "legacy", дублированием в различных библиотеках функциональности, медленным развитием (скорее, отставанием).
Пока же нет стандарта ядра языка и общих принципов для формирования всего кластера диалектов, очевидной системы синтаксиса и семантики. Хотя, что мешает объединить rust, c++17, go, D2, java(или kotlin) в единую систему диалектов, с единой runtime, общими библиотеками, кроме корпоратократии?
Пока же нет стандарта ядра языка и общих принципов для формирования всего кластера диалектов, очевидной системы синтаксиса и семантики. Хотя, что мешает объединить rust, c++17, go, D2, java(или kotlin) в единую систему диалектов, с единой runtime, общими библиотеками, кроме корпоратократии?
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
… Та идея не про общий «runtime» (и .NET, или LLVM тут не причем)! А, именно, про абсолютно разные диалекты. Что то похожее если бы в TopSpeed вместо модулы-паскали-с-с++ были бы языки с++-go-java-d. Самое важное, это понятный синтаксис, возможность интегрировать программы на разных языках в единый проект.
… Практически с++03, с++11 и с++14 это такие диалекты, можно читать и понимать и тот, и другой, но нет средств интегрировать и компилировать в единый проект, без ручного выбора в конфигах ключа компиляции. К тому же, с++ язык многопарадигменный, если строить язык как набор диалектов, то столь сложную систему строить не обязательно, всю область можно покрыть несколькими выделенными подмножествами языка, от «студенческого/школьного», и до «полномасштабного» с/без семантической совместимости с си, и нацеленного на крупные проекты со средствами валидации и strict-владением… про эквивалентность диалектов никто и не говорит, они по определению неэквивалентны, это инструменты нацеленые на решение разных/специфичных задач (DSL), и "колоть орехи" всем стеком диалектов никто не предлагает.
Именно жедание запихнуть все и вся, тогда, привело к появлению монструозных языков PL/1, Ada… путь которых повторяет С++, и желание удовлетворить одним языком всю прикладную область и приводит к тому, что программисты получают от комитета по стандартизации язык который призван решить задачи "давно прошедшей войны".
… Практически с++03, с++11 и с++14 это такие диалекты, можно читать и понимать и тот, и другой, но нет средств интегрировать и компилировать в единый проект, без ручного выбора в конфигах ключа компиляции. К тому же, с++ язык многопарадигменный, если строить язык как набор диалектов, то столь сложную систему строить не обязательно, всю область можно покрыть несколькими выделенными подмножествами языка, от «студенческого/школьного», и до «полномасштабного» с/без семантической совместимости с си, и нацеленного на крупные проекты со средствами валидации и strict-владением… про эквивалентность диалектов никто и не говорит, они по определению неэквивалентны, это инструменты нацеленые на решение разных/специфичных задач (DSL), и "колоть орехи" всем стеком диалектов никто не предлагает.
Именно жедание запихнуть все и вся, тогда, привело к появлению монструозных языков PL/1, Ada… путь которых повторяет С++, и желание удовлетворить одним языком всю прикладную область и приводит к тому, что программисты получают от комитета по стандартизации язык который призван решить задачи "давно прошедшей войны".
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Диалект — один из системы родственных языков. В данном случае: объединенный схожим синтаксисом (для с++ все версии имеют общий синтаксис и семантику в рамках с++98[шаблоны+stl] "по дизайну", и каждая имеет уникальное расширение), языковым ядром(общие библиотеки, шаблонной магией обеспечено, но например java или go имеют собственные библиотеки, не совместимые с с++, т.е. ядра не совместимы в таком виде, желательно чтобы был общий доступ к единой стандартизованной библиотеке из любого диалекта)… а вот как все это будет организованно, единым бекэндом или дубликатами библиотек на разных диалектах — не суть стандарта, это проблемы реализации, а в стандарте должны быть описаны единые принципы строительства синтаксиса, минимальное языковое ядро и описание диалектов, и библиотеки. В аде были требования к среде компиляции, исполнения и валидации компилятора, возможно, что со временем это станет стандартом, аде, borland и topspeed это не помогло.
Вот почему Вы следствие ставите во главу? единая система сборки — это самый простой и логичный путь, но не самоцель, главное — смешение "старого" и нового кода, решение задач адекватными инструментами, а не "гиганской универсальной мухобойкой", средств позволяющих развивать язык не нарушая целостности языковой системы и не генерируя конфликты из-за развития синтаксиса.
Но есть и "ложка дегтя" выбор ядра языка и стандартных библиотек определит всю историю и скорость развития языка и обучение языку.
Вот почему Вы следствие ставите во главу? единая система сборки — это самый простой и логичный путь, но не самоцель, главное — смешение "старого" и нового кода, решение задач адекватными инструментами, а не "гиганской универсальной мухобойкой", средств позволяющих развивать язык не нарушая целостности языковой системы и не генерируя конфликты из-за развития синтаксиса.
Но есть и "ложка дегтя" выбор ядра языка и стандартных библиотек определит всю историю и скорость развития языка и обучение языку.
НЛО прилетело и опубликовало эту надпись здесь
А если подумать? Может Вам помочь llvm-код сгенерированный haskell понять, что делает программа на нем?
многие C-подобные языки хоть и могут общаться через C ABI ушли от него довольно далеко, но «ядро» юникс-стайл поддерживают все, можно за минимальное ядро взять си-рантайм…
Objective-C строгое надмножество C, но его синтаксис далек от предка, но ничего не мешает также надстроить и остальные… си-интерфейс ( ffi ) — это архаизм, дефект вызванный «слабым» линковщиком, не знающим, какие исходники на каком диалекте написаны, в llvm он не намного интелектуальнее, а еще модула-2 продемонстрировала необходимость интелектуального линковщика для многозадачных приложений, в RSX-11 линковщик знал больше, чем «современные», и можно было писать приложения суммарно превосходящие имеющуюся виртуальную память… ELF даже близко не стоит к необходимым требованиям, нет средств к описанию приложения как микросервисов, раздельных куч, рантаймов, динамическая линковка — организованна как костыль… и все эти недостатки Вы нереносите на язык, а как, например, java, реализация это отдельная «фича» и к языку не должна была иметь никакого отношения, и в с++ рантайм, также, сильно ограничен реализацией на средах унаследованным со времен юникс-вей. Как и сейчас, запихнуть различные runtime можно, просто приложение становится такой микро-OS, которая запускает различные нити и runtime вручную, только нужно линковщику объяснить, что если Вы не используете java, то его runtime прилинковывать не нужно, но остается вопрос с маршалингом, если линковщик «тупой», то «маршилить» должен компилятор, вставляю ненужные заглушки для маршалинга в разные диалекты/языки/runtime.
НЛО прилетело и опубликовало эту надпись здесь
Прошу прощения, я вспомнил про де старые публикации, потому, что эти конфликты комитетов по стандартизации случились не в первые, были войны стандартов (между европейским и американским комитетами стандартизации разных языков), особенно ярые бои фортранов (закончившиеся тем, что каждый компьютер имел несколько диалектов, или хотя б свой собственный, "уникальный и неповторимый"), после стандартизации ады в 198х вылез "багофич" с наследованием зависимостей, решение которой было предложено сразу, но комитет отказался, мотивируя соблюдением принципа "совместимости" (решение ограничивало прозрачность зависимостей), тормозил развитие языка, результат известен.
Было очевидно, что появятся новые языки, и чтобы не повторяли прежних ошибок сделали такое предложение, построенное по аналогии с Дэйкстровскими уровнями абстракции.
Страу(в)струп вероятнее всего был в курсе этих процессов, но принял такую точку зрения. Это его персональное решение, логичное или нет — не важно. Вот действия комитета вызывают вопросы.
Оберон — язык как язык, ничего особенного, если бы кто-то из корпораций взял его, то он разросся бы по масштабов c#, таково историческое развитие, сопротивление Вирта проигнорировали бы, видимо по этому и не отдал. Строить "диалекты" корпорации не хотят, хотя можно заработать на обучающей литературе, продавать DSL на заказ, создавать собственные стандарты. Если только один недостаток — распыление "комьюнити", но оно автоматически происходит, просто люди переходят на другие языки, и не возвращаются.
Было очевидно, что появятся новые языки, и чтобы не повторяли прежних ошибок сделали такое предложение, построенное по аналогии с Дэйкстровскими уровнями абстракции.
Страу(в)струп вероятнее всего был в курсе этих процессов, но принял такую точку зрения. Это его персональное решение, логичное или нет — не важно. Вот действия комитета вызывают вопросы.
Оберон — язык как язык, ничего особенного, если бы кто-то из корпораций взял его, то он разросся бы по масштабов c#, таково историческое развитие, сопротивление Вирта проигнорировали бы, видимо по этому и не отдал. Строить "диалекты" корпорации не хотят, хотя можно заработать на обучающей литературе, продавать DSL на заказ, создавать собственные стандарты. Если только один недостаток — распыление "комьюнити", но оно автоматически происходит, просто люди переходят на другие языки, и не возвращаются.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
он имел ввиду дженерики (а-ля C#, которые реализуются в рантайме), хотя дженерики и шаблоны это две большие разницы, которые имеют разный use case.
НЛО прилетело и опубликовало эту надпись здесь
Если я всё правильно понимаю, используя RTTI мы позволим исходнику скомпилиться в случае неправильно указанного типа. В таком случае, я предпочту шаблон и N лишних килобайт в бинарнике, которые будут критичны разве-что в шеллкоде или коде для встраиваемых систем.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Мне кажется для этой цели и был создан Rust. Хотя от нового мощного C# v2 я бы не отказался. Но язык такой гибкий, что практически любые фичи можно добавлять прямо в него, не перелопачивая всё, а учитывая Rosylin можно самому описывать диалект не просто, а очень просто. Добавление кортежей в шарп на CLRium'е 2015 года заняло ровно 50 строчек кода, если я правильно помню. Прикручивай к этому всему подсветку в студии — и можно выпускать новую версию :)
Поэтому managed-языки имхо будут вскоре очень сильно потеснены шарпом, и влезать туда нет смысла — убьет.
А что касается системного — то уже есть раст, который и задумывался как "более лучший С++".
В таком случае как раз лучше тогда войти в комитет по расту и там ускорять внедрение новых фич.
Поэтому managed-языки имхо будут вскоре очень сильно потеснены шарпом, и влезать туда нет смысла — убьет.
А что касается системного — то уже есть раст, который и задумывался как "более лучший С++".
В таком случае как раз лучше тогда войти в комитет по расту и там ускорять внедрение новых фич.
Rust по какой-то причине (намеренно?) сделан внешне слишком не-сиподобным. В отличие от C# или Java, его синтаксис тяжело воспринимается. Не знаю почему, но это так.
Я воспринимаю все это лишь как попытки и приближения к идеалу. Сейчас хорошо бы, если Rust, Swift, D и Go откусят от С и C++ приличные куски… посуществуют какое-то время все вместе… а там будет видно.
Я воспринимаю все это лишь как попытки и приближения к идеалу. Сейчас хорошо бы, если Rust, Swift, D и Go откусят от С и C++ приличные куски… посуществуют какое-то время все вместе… а там будет видно.
НЛО прилетело и опубликовало эту надпись здесь
Мне кажется, что он тяжело воспринимается не из-за синтаксиса (его как раз упростили), а из-за того, что компилятор должен убедиться в том, что все в порядке. То есть элементарный код вида
```csharpConsole.WriteLine("Введите число");
int i = int.Parse(Console.ReadLine());
Console.WriteLine("Вы ввели {0}", i);
Превращается вот в это:
```rustprintln!("Введите число");
let mut guess = String::new();
io::stdin().read_line(&mut guess)
.expect("Не удалось прочитать строку");
let guess: u32 = guess.trim().parse()
.expect("Пожалуйста, введите число!");
println!("Вы ввели {}", guess);
И тут уже нужно разбираться, что за expect, что за передача с '&' и так далее. Тут проблема не в синтаксисе, а в том, что в этом языке защитное программирование возведено в абсолют и только оно позволяет компилятору грамотно делать свою работу. Пример на шарпе можно также переписать, чтобы оно не бросало исключение, и это будет весьма небольшое изменение (Parse на TryParse), но зачастую на это "забивают", либо дописывают потом "щас будем вводить только число, а когда прототип будет работать, добавим уже нормальную проверку". Да, на расте есть unwrap, но за его использование очень ругают, поэтому весь код обрастает кучей проверок. Для системного программирования это хорошо, ошибок раст не пропустит. Но порог вхождения сильно повышается. Синтаксис этого не меняет, наоборот, синтаксис очень короткий и информативный. Не опускаясь до абсурдности вроде J. Он мог бы быть лучше (возможно), но это явно не самый плохой синтаксис из тех, что мог бы быть. С точки зрения теории принятия решения, оптимальное решение — которое не нравится всем в равной степени. А не то, которой полностью устраивает кого-либо.
```csharpConsole.WriteLine("Введите число");
int i = int.Parse(Console.ReadLine());
Console.WriteLine("Вы ввели {0}", i);
Превращается вот в это:
```rustprintln!("Введите число");
let mut guess = String::new();
io::stdin().read_line(&mut guess)
.expect("Не удалось прочитать строку");
let guess: u32 = guess.trim().parse()
.expect("Пожалуйста, введите число!");
println!("Вы ввели {}", guess);
И тут уже нужно разбираться, что за expect, что за передача с '&' и так далее. Тут проблема не в синтаксисе, а в том, что в этом языке защитное программирование возведено в абсолют и только оно позволяет компилятору грамотно делать свою работу. Пример на шарпе можно также переписать, чтобы оно не бросало исключение, и это будет весьма небольшое изменение (Parse на TryParse), но зачастую на это "забивают", либо дописывают потом "щас будем вводить только число, а когда прототип будет работать, добавим уже нормальную проверку". Да, на расте есть unwrap, но за его использование очень ругают, поэтому весь код обрастает кучей проверок. Для системного программирования это хорошо, ошибок раст не пропустит. Но порог вхождения сильно повышается. Синтаксис этого не меняет, наоборот, синтаксис очень короткий и информативный. Не опускаясь до абсурдности вроде J. Он мог бы быть лучше (возможно), но это явно не самый плохой синтаксис из тех, что мог бы быть. С точки зрения теории принятия решения, оптимальное решение — которое не нравится всем в равной степени. А не то, которой полностью устраивает кого-либо.
Извиняюсь, хабр что-то комментарий переоформил как-то дико.
Console.WriteLine("Введите число");
int i = int.Parse(Console.ReadLine());
Console.WriteLine("Вы ввели {0}", i);
println!("Введите число");
let mut guess = String::new();
io::stdin().read_line(&mut guess)
.expect("Не удалось прочитать строку");
let guess: u32 = guess.trim().parse()
.expect("Пожалуйста, введите число!");
println!("Вы ввели {}", guess);
Здесь основное отличие — паттерн обработки ошибок. А не управление ресурсами, время жизни и т.п.
Rust использует ADT и пакует ошибки как второй вариант результата функции. А у C# возможные ошибки в сигнатуре не фигурируют.
А по поводу защитного программирования — я сейчас, когда пишу на C++, регулярно думаю, что с какой-то фичей из Rust мог бы написать 20 строчек вместо 200.
Rust использует ADT и пакует ошибки как второй вариант результата функции. А у C# возможные ошибки в сигнатуре не фигурируют.
А по поводу защитного программирования — я сейчас, когда пишу на C++, регулярно думаю, что с какой-то фичей из Rust мог бы написать 20 строчек вместо 200.
Дело не в том, что паттерн обработок ошибок другой. А то, что в большинстве реально используемых языков на него можно забить. Ну Unhandled Exception, подумаешь! Очень много кода не проверяет ссылку на null, например, ибо предполагается "получили null — зачем проверять? Все равно при первом же доступе к любому члену или методу выкинется эксепшн". А в расте нужно ВСЕ ВОЗМОЖНЫЕ кейзы прорабатывать. Грубо говоря, если элементарная программка на С++ занимает разработку месяц, из которой сначала пишется прототип за неделю, а потом 3 недели вылавливают баги, то на расте потратишь 3 недели, но все эти 3 недели будешь бороться с компилятором, чтобы он позволил твоему коду запуститься. Да, после запуска с 99% вероятностью код можно сразу пускать в продакшн, багов там нет. Но первичный результат "хоть как-то работает" будет на плюсах почти сразу, а на расте будет "всё или ничего". Либо правильно работающая программа, либо не компилирующаяся. В плюсах весьма вероятно получить работающее решение, но падающее при некоторых хитрых условиях. Компилятор же раста скорчит морду, и программисту придется долго разбираться, что же там не так. И хотя человек не прав, а компилятор — прав, в первом случае у него иллюзия, что он быстро написал, и просто приводил в порядок, а во втором случае ему кажется, что компилятор вставляет палки в колеса, мешает жить и вообще без этих долбаных проверок жилось бы намного лучше.
Хотел ответить развёрнуто, но не буду. Аргументы и так известны. Скажу просто. В С++ сделать неправильно просто, а правильно — не просто сложно, а требует иногда борьбы с компилятором. В Rust наоборот, сделать правильно проще, чем неправильно — пусть и порог этого действа повыше. И это есмь хорошо. Потому что лично я устал обрабатывать все краевые и не очень случаи своей головой. И я хочу работать с языком, у которого сравнительно простая и понятная семантика (да-да, borrow checker — это три простых правила и немного тренировки), а не 1500 страниц стандарта, забитые наполовину undefined behavior и implementation defined. Дальше продолжать не буду, дабы не надоедать.
Что значит правильно, неправильно? Какое то странное понятие использования инструмента. С++ позволяет сделать так как ты хочешь, а не так как хочет компилятор в случае раста. Ну хочу я написать код который в определённых случаях будет давать UB, но я знаю что буду использовать его только для случаев в которых UB невозможен.
Просто С++ более требователен к опыту программиста чем другие языки.
Просто С++ более требователен к опыту программиста чем другие языки.
Мне вот интересно насчёт этого аргумента про "как захочу я, а не компилятор". Сколько у вас реально было кода, в котором нужно было буквально перебирать байты вручную? Действительно ли настолько много, что защита помешала бы буквально во всей программе? Мне например такая "свобода всегда и везде" неудобна. Мне гораздо удобней иметь возможность снять такую защиту ровно там где нужно. И в будущем знать, что если я накосячил, то в первую очередь надо смотреть unsafe блоки. Знать, что эти блоки надёжно изолированы, а не просачиваются в виде указателей повсюду.
Аналогия из реальной жизни. Почему эти нехорошие электрики закрывают щитки крышкой, а иногда и на замок? Для чего прячут кабели? А для того, чтобы жильцам было удобно ходить, а не приходилось перепрыгивать через оголённые кабели. Прыжок не туда == шашлык.
Хитрого системного кода мало. Просто системного и прикладного — много. И вот его хотелось бы писать удобно, а не прыгать через раскиданные на полу высоковольтные кабели.
Аналогия из реальной жизни. Почему эти нехорошие электрики закрывают щитки крышкой, а иногда и на замок? Для чего прячут кабели? А для того, чтобы жильцам было удобно ходить, а не приходилось перепрыгивать через оголённые кабели. Прыжок не туда == шашлык.
Хитрого системного кода мало. Просто системного и прикладного — много. И вот его хотелось бы писать удобно, а не прыгать через раскиданные на полу высоковольтные кабели.
Завернул в unsafe, и лепи что хочешь )
"получили null — зачем проверять? Все равно при первом же доступе к любому члену или методу выкинется эксепшн".
В managed языках. А в C++ под linux обычно будет SIGSEGV и хватит. А если в kernelspace, то там свой хендлер для обработки NULL dereference, обычно будет паника.
Но первичный результат "хоть как-то работает" будет на плюсах почти сразу, а на расте будет "всё или ничего".
Если не хочется обрабатывать ошибки, то можно спокойно использовать unwrap/expect и при ошибке будет паника, что не сильно отличается от segfault'а.
Синтаксис Rust в достаточной степени C-подобен. Просто исправили очевидные просчеты, на счет необязательных фигурных и лишних круглых скобок во вложенных операторах. А с какой стороны тип от имени переменной писать — большая ли разница?
Мне кажется, что наоборот стоит развивать. Чтобы избавиться от этих унаследованных проблем им бы надо поменьше думать об обратной совместимости, безжалостно выкидывая старый некрасивый код из стандартной библиотеки. Да, возникнут проблемы со старым кодом, но так язык начнет развиваться в более лучшую, очищаться от мусора.
а, возникнут проблемы со старым кодом, но так язык начнет развиваться в более лучшую, очищаться от мусора.
и новыми компиляторами никто не будет пользоваться, и т.о. вы только закопаете язык в ещё более глубокую яму: целая гора хорошего, полезного, библиотечного кода написана именно на C++/C, и остаётся актуальным годами, даже если он заброшен авторами. Обратная совместимость компиляторов — это хорошо, особенно для нативного кода. Очень плохо, когда текущий компилятор замусоривается просто потому, что из года в год его стараются сделать как можно более избыточным.
Убедительно.
Я буду пользоваться.
Ну потрачу пару дней на то, чтобы привести все старые проекты в соответствие с новыми правилами, это не такая уж и большая цена))
Библиотечный код перепишут создатели библиотек, это тоже не так уж и сложно. Что заброшено авторами — то давно пора на помоечку, все равно там баги никто не исправляет.
Ну потрачу пару дней на то, чтобы привести все старые проекты в соответствие с новыми правилами, это не такая уж и большая цена))
Библиотечный код перепишут создатели библиотек, это тоже не так уж и сложно. Что заброшено авторами — то давно пора на помоечку, все равно там баги никто не исправляет.
А у вас останется время на разработку своего продукта, если вы будете постоянно переписывать чужие проекты просто для того, чтобы они скомпилировались?
А если пулл?
Спасибо, порадовали. Авторам библиотек порой лень принять пулл-реквест, а вы мне тут заливаете о том, что авторы будут моментально подстраиваться под новый стандарт.
А вообще, это отличный способ изолировать opensource от всех остальных.
А если пулл?
Библиотечный код перепишут создатели библиотек,
Спасибо, порадовали. Авторам библиотек порой лень принять пулл-реквест, а вы мне тут заливаете о том, что авторы будут моментально подстраиваться под новый стандарт.
А вообще, это отличный способ изолировать opensource от всех остальных.
opensource на то и opensource, что можно форкнуть.
к тому же пулреквест — это автору надо думать над задачей, которая лично ему скорее всего и не нужна;
а приведение библиотеки в соответствие с новым стандартом — это тупая работа: перекомпиляция и исправление ошибок, которые заботливо покажет компилятор; думать не надо, так как вся логика уже известна и продумана, нужно просто поправить синтаксис.
к тому же пулреквест — это автору надо думать над задачей, которая лично ему скорее всего и не нужна;
а приведение библиотеки в соответствие с новым стандартом — это тупая работа: перекомпиляция и исправление ошибок, которые заботливо покажет компилятор; думать не надо, так как вся логика уже известна и продумана, нужно просто поправить синтаксис.
Ок. Новый стандарт убирает темплейты. Вопрос: как вы будете теперь будете пользоваться бустом на новом компиляторе?
Или вы заботливо перепишете весь буст?
Или вы заботливо перепишете весь буст?
Зачем убирать темплейты? Убирать нужно инклуды и лексический препроцессор. Вместо этого вводить полноценные модули (без компромиссов со старой системой инклудов), синтаксические макросы (и здесь же синтаксический препроцессор).
Вы не ответили на поставленный вопрос: что вы будете делать, если решат убрать темплейты?
p.s. а если уберут инклуды — то что вы будете делать с тем-же бустом или GLFW?
p.s. а если уберут инклуды — то что вы будете делать с тем-же бустом или GLFW?
А если уберут операторы if и else?
Вопрос бессмысленный. Убирать надо не все подряд, а то что надо — в частности, инклуды и препроцессор.
Что делать с бустом? Переделывать на модули, очевидно. Поддерживать две версии какое-то время. В старой — на инклудах — просто фиксить баги, развивать только новую — с использованием новых возможностей. Это нормально, например тот же буст вы сейчас компилятором msvc 6 (98 года) не соберете.
Вопрос бессмысленный. Убирать надо не все подряд, а то что надо — в частности, инклуды и препроцессор.
Что делать с бустом? Переделывать на модули, очевидно. Поддерживать две версии какое-то время. В старой — на инклудах — просто фиксить баги, развивать только новую — с использованием новых возможностей. Это нормально, например тот же буст вы сейчас компилятором msvc 6 (98 года) не соберете.
Вопрос не бессмысленный: я предоставил тот самый случай несовместимости компиляторов разных версий, за которую вы так агитируете. Отвечайте на первый вопрос: что вы будете делать с бустом, если уберут шаблоны? Отмазки "это ведь полезная фича" не рассматриваются: ведь не вы решаете, что войдёт в очередной стандарт.
Отказ от пулл-реквестов: и какой тут тогда опенсорс, если никто не будет принимать изменения от сообщества? Вы агитируете к стагнации.
Другое расширение файла (например "cpp2")
А на будущее — #pragma version в начале каждого файла (это кстати полезно для всех разработчиков новых языков)
Внести в стандарт требование поддержки всех версий и правила взаимодействия кода между версиями
Определить конкретные сроки, в течении которых будут поддерживаться те или иные версии (например 5 лет на одновременное существование двух версий — вполне достаточно)
Начиная с какой-то версии языка, некоторая старая версия объявляется неподдерживаемой и новые компиляторы отказываются компилировать старый код.
Отвечая на ваш странный вопрос — что делать с Бустом если уберут шаблоны: очевидно переписывать Буст на новые средства без шаблонов (например на синтаксические макросы, если таковые появятся). Поддерживать две версии Буста в течение срока поддержки.
А на будущее — #pragma version в начале каждого файла (это кстати полезно для всех разработчиков новых языков)
Внести в стандарт требование поддержки всех версий и правила взаимодействия кода между версиями
Определить конкретные сроки, в течении которых будут поддерживаться те или иные версии (например 5 лет на одновременное существование двух версий — вполне достаточно)
Начиная с какой-то версии языка, некоторая старая версия объявляется неподдерживаемой и новые компиляторы отказываются компилировать старый код.
Отвечая на ваш странный вопрос — что делать с Бустом если уберут шаблоны: очевидно переписывать Буст на новые средства без шаблонов (например на синтаксические макросы, если таковые появятся). Поддерживать две версии Буста в течение срока поддержки.
Включающих все лучшее языков и так достаточно. Тот же C# например, в свете последних новостей — думаю, будет развиваться в сторону кроссплатформенности. Это единственное, чего ему не хватало.
Полностью согласен. Я слабо представляю как все это С++ легси поддерживать. Каждая новая версия стандарта добавляет сотню страниц к спецификации языка. Уже сейчас стандарт С++ это кажется что-то около 1500 страниц. Я сомневаюсь что их кто-то осиливает и применяет правильно. Скорее всего большая часть программистов на С++ эту спецификацию даже не читали и пишут как умеют. В итоге код работает не благодаря, а вопреки. А поддержка превращается в ужас.
пишут на C with classes, который чудом компилится. Иногда шаблонизируют. Иногда с лямбдами.
НЛО прилетело и опубликовало эту надпись здесь
Спека к языку настолько большая, что рассчитывать на полное знание языка довольно опрометчиво. Достаточно знать не меньше, чем средний интервьювер.
Очень высокомерно. Таких разрабов большинство, потому что свыше 99% написанного и работающего кода именно так написано и именно так работает. ИМХО, писать прикладной код в строгом соответствии со стандартом — это итальянская забастовка.
НЛО прилетело и опубликовало эту надпись здесь
А как вы пишете по-русски, не сверяясь с учебниками? Если момент скользкий — тогда заглядываю в стандарт.
НЛО прилетело и опубликовало эту надпись здесь
Я говорил о строгом соответствии стандарту. Что-то вроде знаковости char'а или сдвига знакового целого вправо. Вот, например, реализация референсного кодека HEVC (новый стандарт сжатия видео) полагается на сдвиг вправо вместо деления, а эта операция implementation-defined для си/плюсов. Получается, что стандарт зависит от платформы. Дикость вроде, но на подавляющем большинстве платформ этот самый сдвиг сделан одинаково.
P. S. меня эта штука со сдвигом возмутила немало в своё время — если есть знающие люди, которые могут объяснить такой, казалось бы, нонсенс — был бы рад услышать объяснение.
P. S. меня эта штука со сдвигом возмутила немало в своё время — если есть знающие люди, которые могут объяснить такой, казалось бы, нонсенс — был бы рад услышать объяснение.
НЛО прилетело и опубликовало эту надпись здесь
Мусора не должно быть. Implementaion-dependent всё-таки не undefined behaviour. На х86 и ARM v7-8 я видел, что генерится инструкция арифметического сдвига, которая округлит результат деления к минус бесконечности. Но смысл не в этом. Смысл в том, что чем сложнее проектируемая система, тем больше шанс наткнуться на какую-нибудь "поганку", чьё поведение не описывается стандартами. Именно поэтому строгое следование правилам становится итальянской забастовкой. Приходится вместо этого изворачиваться, и становиться С/С++ программистом.
Более того, по опыту совместной работы с хорошими С++ программистами, могу сказать, что они со временем задирают порог вхождения в проект. В командах работают разные люди. Кто-то сильный research'ер, но любит конструкций в духе Александреску. Как его осуждать? Лучше пусть будет С/С++ и работающий проект, чем упражнения в прекрасном.
Более того, по опыту совместной работы с хорошими С++ программистами, могу сказать, что они со временем задирают порог вхождения в проект. В командах работают разные люди. Кто-то сильный research'ер, но любит конструкций в духе Александреску. Как его осуждать? Лучше пусть будет С/С++ и работающий проект, чем упражнения в прекрасном.
НЛО прилетело и опубликовало эту надпись здесь
Я не говорю о крайностях. Есть исследовательские проекты. Их участникам не до гайдлайнов. Я сам в таких участвовал — половина команды кандидаты наук, и вообще предпочитают матлаб. Проект ведётся на С/С++, потому что потом на основе кода нужно сделать ASIC. Там редкие, штучные люди, если после них код невозможно понять, по привлекут умного студента/стажёра/джуниора, и он со слов гуру приведёт код в читаемое состояние. А дополнительное время не research приведёт к написанию научной статьи, но никак не к хорошему коду.
Вот и получается, что солянка из С/С++ работает как наименьший общий знаменатель. На мой взгляд, коду вообще не следует поклоняться. Многие фундаментальные вещи написаны так, что внутрь лучше не смотреть.
Вот и получается, что солянка из С/С++ работает как наименьший общий знаменатель. На мой взгляд, коду вообще не следует поклоняться. Многие фундаментальные вещи написаны так, что внутрь лучше не смотреть.
НЛО прилетело и опубликовало эту надпись здесь
Больше мусора богу мусора!
Больше костылей к трону костылей!
Больше костылей к трону костылей!
> string_view же выглядит как затычка, для тех, кто не освоил константные ссылки и shared_ptr
string_view нужен чтобы передать read-only _подстроку_ без копирования данных, аналогов ему до сих пор не было.
string_view нужен чтобы передать read-only _подстроку_ без копирования данных, аналогов ему до сих пор не было.
Не хватает ссылки на другие отчёты по встрече. Например: C++17 and other future highlights of C++ by Jens Weller.
Файловая система. "Отличная штука! Была бы, если бы вошла в стандарт лет 15 назад."
Сейчас она менее полезна?
string_view. "будет хорошо смотреться в интерфейсах, какого-то принципиального быстродействия по сравнению с двумя предыдущими способами не даст"
Почему вы здесь оцениваете что-то только с позиции быстродействия?
Параллельные алгоритмы. "Классическая ситуация «к 14-ти стандартам прибавился 15-ый»"
Стандарта не было, теперь он есть, он один.
Специальные математические функции. "Ну боже мой, почему этому всему не нашлось места в какой-нибудь лежащей далеко в углу математической библиотеке"
А они чему-то мешают? Да, можно было бы легко прожить без них, но ведь мы лишились модулей не из-за сферических гармоник, зачем паниковать?
С помощью ranged-for теперь можно бегать по диапазонам, в которых начало и конец имеют разные типы.
Это полезный шаг в сторону ranges, о чём вы не упомянули.
Концепты. "Я не знаю как всё там в комитете варится внутри"
Тогда зачем пишете? Они регулярно об этом рассказывают на конференциях, на интервью, публикуют результаты встреч и отчёты. Подобное замечание смотрится крайне непрофессионально.
Унифицированный синтаксис вызова. "И ведь предлагают его Bjarne Stroustrup и Herb Sutter."
Авторитет не должен давлеть над здравыми доводами.
Итог: слишком много эмоций, слишком мало полезной информации и анализа принятых решений.
Файловая система. "Отличная штука! Была бы, если бы вошла в стандарт лет 15 назад."
Сейчас она менее полезна?
string_view. "будет хорошо смотреться в интерфейсах, какого-то принципиального быстродействия по сравнению с двумя предыдущими способами не даст"
Почему вы здесь оцениваете что-то только с позиции быстродействия?
Параллельные алгоритмы. "Классическая ситуация «к 14-ти стандартам прибавился 15-ый»"
Стандарта не было, теперь он есть, он один.
Специальные математические функции. "Ну боже мой, почему этому всему не нашлось места в какой-нибудь лежащей далеко в углу математической библиотеке"
А они чему-то мешают? Да, можно было бы легко прожить без них, но ведь мы лишились модулей не из-за сферических гармоник, зачем паниковать?
С помощью ranged-for теперь можно бегать по диапазонам, в которых начало и конец имеют разные типы.
Это полезный шаг в сторону ranges, о чём вы не упомянули.
Концепты. "Я не знаю как всё там в комитете варится внутри"
Тогда зачем пишете? Они регулярно об этом рассказывают на конференциях, на интервью, публикуют результаты встреч и отчёты. Подобное замечание смотрится крайне непрофессионально.
Унифицированный синтаксис вызова. "И ведь предлагают его Bjarne Stroustrup и Herb Sutter."
Авторитет не должен давлеть над здравыми доводами.
Итог: слишком много эмоций, слишком мало полезной информации и анализа принятых решений.
Можно, пожалуйста, пример, в котором было бы полезно использовать ranged-for с разными типами начала и конца? А то я что-то вообще понять не могу, зачем оно надо.
Посмотрите, как сделан istream_iterator сейчас. Он выполняет сразу две функции — функцию "нормального" итератора, который позволяет считать что-то из потока, и функцию "нулевого", стандартно-сконструированного итератора, чья задача — только сравниваться с "нормальным" через == или !=.
Видимо, для избежания подобного дублирования и введена такая конструкция. Теперь в аналогичном месте с range-for end() сможет возвращать какой-нибудь end_iterator_t, который будет обладать специальной семантикой сравнения.
Видимо, для избежания подобного дублирования и введена такая конструкция. Теперь в аналогичном месте с range-for end() сможет возвращать какой-нибудь end_iterator_t, который будет обладать специальной семантикой сравнения.
Суть в том, что "конец" по сути своей не обязан являться итератором. Он должен быть "стражем", быть способным сравниться с итератором, пробегающим по массиву, но не более. Получается, что стандарт до этого требовал от "конца" чего-то необязательного, излишнего. Ломалась одна из основополагающих концепций языка С++ — "Вы не платите за то, что не используете". Мы не использовали итераторные возможности "конца", но "платили" за них.
Ещё один пример в копилку — пара итераторов над функцией-генератором. В Boost сейчас это сделано через std::function внутри, просто чтобы иметь "пустое" состояние сохранённой функции для маркера конца. А если итератор конца будет другого типа — можно будет спокойно вкладывать функтор в первый итератор по значению, не используя кучу
Господа выше ответили достаточно верно. Добавлю ссылку на оригинальный пост от Эрика Ниблера, автора ranges proposal и их пробной реализации в рамках С++14: http://ericniebler.com/2014/02/16/delimited-ranges/
Там как раз рассматривается подходящий пример, о котором здесь не упомянули — итерация по терминированной нулём С-строке. С итератором начала всё ясно — это, собственно, указатель на строку. А вот как быть с концом? Проще всего было бы в качестве конца использовать указатель на последний (нулевой) символ. Но пока мы не пройдём по строке целиком, мы не знаем, где она кончается!
Значит, нам нужна дополнительная сущность. Это может быть специальное состояние в том же итераторе. Тогда это уже не может быть простой указатель. Этот случай с istream_iterator разобрал borisko выше. Проблема — плата в рантайме за хранение состояние и его проверку.
Другой подход — использовать другой тип для конца. Не итератор, а страж (sentinel). Тогда итератор начала остаётся просто указателем, а "итератор" конца становится стражем. В страже нет вообще никакого состояния, но операция сравнения итератора со стражем определена таким образом, что итератор просто сравнивается с нулём. И это операция выбирается на этапе компиляции! Никаких накладных расходов в рантайме. Так же эффективно, как голый цикл.
Там как раз рассматривается подходящий пример, о котором здесь не упомянули — итерация по терминированной нулём С-строке. С итератором начала всё ясно — это, собственно, указатель на строку. А вот как быть с концом? Проще всего было бы в качестве конца использовать указатель на последний (нулевой) символ. Но пока мы не пройдём по строке целиком, мы не знаем, где она кончается!
Значит, нам нужна дополнительная сущность. Это может быть специальное состояние в том же итераторе. Тогда это уже не может быть простой указатель. Этот случай с istream_iterator разобрал borisko выше. Проблема — плата в рантайме за хранение состояние и его проверку.
Другой подход — использовать другой тип для конца. Не итератор, а страж (sentinel). Тогда итератор начала остаётся просто указателем, а "итератор" конца становится стражем. В страже нет вообще никакого состояния, но операция сравнения итератора со стражем определена таким образом, что итератор просто сравнивается с нулём. И это операция выбирается на этапе компиляции! Никаких накладных расходов в рантайме. Так же эффективно, как голый цикл.
Они регулярно об этом рассказывают на конференциях, на интервью, публикуют результаты встреч и отчёты.
Я с какого-то момента перестал верить и пришел к выводу, что говорят они что-то на публику одно, а внутри происходит что-то другое, о чём я не знаю, поэтому и построил так предложение. Путь концептов в стандарт слишком долог и тернист, даже по меркам С++.
Не столько жалко отсутствия модулей, сколько networking
Сам в свое время ушел с c++ на java. Могу сказать, что послужило причиной в моем случае.
Не сборщик мусора, не синтаксические «плюшки», а стандартная библиотека и удобство использования сторонних библиотек… когда для написания простейшей сетевой утилиты, тебе нужно выбирать библиотеку для работы с сетью, убедиться что она работает с твоим компилятором и работает на выбранных тобой платформах, то это уж извините.
Не сборщик мусора, не синтаксические «плюшки», а стандартная библиотека и удобство использования сторонних библиотек… когда для написания простейшей сетевой утилиты, тебе нужно выбирать библиотеку для работы с сетью, убедиться что она работает с твоим компилятором и работает на выбранных тобой платформах, то это уж извините.
Описанный Вами недостаток относится не конкретно к С++, а в принципе к любому языку, который использует трансляцию в машинный код, а не в байт-код виртуальной машины. Да, часто приходится собирать нужные библиотеки одним и тем же компилятором, да ещё примерно с одними и теми же флагами. В стандартную библиотеку в любом случае всё не запихаешь.
Не хватает пункта «Плохо, но не катастрофично»
Парадокс комитета С++: «В стандарте не должно быть непроверенных решений. Но стандарт из одних проверенных решений никому не нужен». Моё мнение — комитету надо чаще выпускать версии.
Сообществу же посоветую не рассматривать голый С++ последнего стандарта как то, на чём предлагается реально кодить живому человеку. Это как линукс без инит-системы. Надо накидать побольше своих библиотек, и тогда уже пользоваться.
И да, я прямо сейчас на работе ковыряю проект, разные модули которого возвращают мне char[], wchar[], std::string, std::vector, QString и QByteArray и ещё структуры с одной строкой, сгенерённые protobuf. Это всё из-за разнобиблиотечия. Это уже просто неотъемлемая часть С++ и не надо ожидать от комитета С++ ощутимых подвижек. Всё, хоть сколько-то новое, не войдёт в стандарт, а всё, что вошло, тыщу лет есть в других языках.
Сообществу же посоветую не рассматривать голый С++ последнего стандарта как то, на чём предлагается реально кодить живому человеку. Это как линукс без инит-системы. Надо накидать побольше своих библиотек, и тогда уже пользоваться.
И да, я прямо сейчас на работе ковыряю проект, разные модули которого возвращают мне char[], wchar[], std::string, std::vector, QString и QByteArray и ещё структуры с одной строкой, сгенерённые protobuf. Это всё из-за разнобиблиотечия. Это уже просто неотъемлемая часть С++ и не надо ожидать от комитета С++ ощутимых подвижек. Всё, хоть сколько-то новое, не войдёт в стандарт, а всё, что вошло, тыщу лет есть в других языках.
Подскажите мне, пожалуйста, библиотеку для С++ которая реализует функциональность модулей.
Всему остальному я аналоги найти смогу.
Всему остальному я аналоги найти смогу.
НЛО прилетело и опубликовало эту надпись здесь
"без ручного написания макросов" ну вот по этому пункту как раз и "аналог". Неполный конечно. Автор предложения по рефлексии свою библиотеку написал, неплохую (и компайл, и рантайм). В конце концов, есть еще вариант написать расширение для clang (на woboq эмулятор moc делали).
Просто ну вот с модулями вообще никак, даже приблизительно. Самый далекий аналог — precompiled headers.
Просто ну вот с модулями вообще никак, даже приблизительно. Самый далекий аналог — precompiled headers.
Про транзакционную память ничего не ясно. Чем отличается представленный кусок кода от аналогичного без synchronized?
Могу лишь предположить, что это аналог @synchronized из objective-c. То есть вокруг блока кода объявляется критическая секция, которая при наличии нескольких потоков гарантирует то, что в данный момент только один поток исполняет этот блок кода.
Другими словами: вызываем функцию в несколько потоков без synchronized — в выводе получаем разные веселые вещи вроде
При вызове с synchronized получим правильный последовательный инкремент
и т.д.
Другими словами: вызываем функцию в несколько потоков без synchronized — в выводе получаем разные веселые вещи вроде
before 0
after 1
before 1
after 2
before 0
after 1
before 2
after 3
При вызове с synchronized получим правильный последовательный инкремент
before 0
after 1
before 1
after 2
before 2
after 3
before 3
after 4
и т.д.
Я так понимаю, что-то аналогичное lock в C#, то есть объявялется критическая секция, которая компиляторов трансформируется в неявное использование монитора. Реализация может отличаться, но смысл думаю такой же.
Транзакционная память не использует блокировок, но допускает перезапуск кода в случае конфликта. Код выполняется как-будто он изменяет все переменные, но реальные изменения происходят только при завершении транзакции. При этом происходит проверка, что больше и кто эти (и просто прочитанные) переменные не использовал. Современные процессоры имеют даже аппаратную поддержку для этого.
Извините за немного сторонний вопрос: В новейших стандартах C++ реализовали ли properties для объектов?
Есть ли обязательный блок (по типу finally в некоторых языках) для исключений?
Есть ли обязательный блок (по типу finally в некоторых языках) для исключений?
Нет и нет. И если первое — просто синтаксический сахар, то второе в С++ в принципе не нужно. Загуглите RAII.
И если первое — просто синтаксический сахар
Все суть синтаксический сахар, кроме машинного кода — начиная от if then else. Однако, удобно.
то второе в С++ в принципе не нужно. Загуглите RAII
То-есть, нет. Спасибо. Я, конечно, посмотрю, но почему именно в С++ не нужно? Я ж не срача ради, а познания для.
Если пихать в язык, всё, что удобно — получится очередной монстр а-ля С++ со стандартом на 1500 страниц, который в принципе ни один человек в мире даже не знает. Так что тут нужно стараться в язык добавлять только самые необходимые вещи, которым свойства, по-моему, никак не являются.
По RAII просто почитайте в той же Вики, что это за подход. Суть в том, что доступ к ресурсу ведётся через локальный объект, деструктор которого будет вызван автоматически, как только объект покинет область видимости. В деструкторе пишете код, который освобождает ресурс, и тогда при выходе локального объекта, через который ведётся доступ к ресурсу, из области видимости, ресурс гарантированно освобождается. И не надо никаких finally.
По RAII просто почитайте в той же Вики, что это за подход. Суть в том, что доступ к ресурсу ведётся через локальный объект, деструктор которого будет вызван автоматически, как только объект покинет область видимости. В деструкторе пишете код, который освобождает ресурс, и тогда при выходе локального объекта, через который ведётся доступ к ресурсу, из области видимости, ресурс гарантированно освобождается. И не надо никаких finally.
которым свойства, по-моему, никак не являются.
Как и RTTI и куча других вещей, ну да ладно.
Так что тут нужно стараться в язык добавлять только самые необходимые вещи
Так самые необходимые вещи, это как известно, операции "сдвиг влево/вправо" и "чтение/запись в ячейку".
По RAII просто почитайте в той же Вики, что это за подход.
Да я уж прочел. Только "проходной" блок finally используется не только для осовобождения ресурсов. Нет так нет, я просто поинтересовался у знающих плюсы.
finally можно не напрягаясь написать за пару минут http://ideone.com/fXYjQq
Хорошая идея. Насколько я понимаю, срабатывает при удалении фиктивного объекта, когда тот выходит из зоны видимости?
finally может быть вложенным, перемешанным с catch, иметь после себя код, который выполняется только в случае отсутствия исключений, но после finally.
finally может быть вложенным, перемешанным с catch, иметь после себя код, который выполняется только в случае отсутствия исключений, но после finally.
Насколько я понимаю, срабатывает при удалении фиктивного объекта, когда тот выходит из зоны видимости?Ага
finally может быть вложенным, перемешанным с catch, иметь после себя код, который выполняется только в случае отсутствия исключений, но после finally.Ну ту да есть проблемка перемешать с catch не получится. А для того чтобы выполнился после кетча и потом выполнился ещё код то нужно брать в фигурные скобки, вообщем жить можно если очень прям нужно. Но случаи когда нужен блок finally в С++ очень редкие.
Если не просто "пихать", а сочетать и согласовывать все фичи между собой для достижения полной консистентности, то получится именно то что нужно. И да, я черт возьми хочу язык, который объединяет все фичи C, C++, Delphi, Objective C, D, Go, Rust, Swift, Java, C#, Scala, Nemerle, Nim… Именно объединяет в согласованном и идеально продуманном виде.
Я, конечно, посмотрю, но почему именно в С++ не нужно? Я ж не срача ради, а познания для.
Потому что RAII по идее замена finally.
C++ и так уже состоит из одних сплошных костылей.
Даже ключевое слово auto стали использовать для этих целей потому, что оно уже было зарезервировано в Си в тыща девятьсот лохматом году, чтобы обозначать размещение переменных на стеке (в противоположность слову register), но не использовалось в C++ от слова совсем, вот и пихнули свободное относительно подходящее по смыслу ключевое слово. Так что просто повезло, а то сделали бы какой-нибудь __var, и было бы ещё веселее.
Реально проще с нуля новый язык создать, чем это все реанимировать пытаться. D на мой вкус тоже немножко тяжеловат, однако он объективно в 2-3 раза проще пресловутых крестов и код на нем крайне прозрачный.
Даже ключевое слово auto стали использовать для этих целей потому, что оно уже было зарезервировано в Си в тыща девятьсот лохматом году, чтобы обозначать размещение переменных на стеке (в противоположность слову register), но не использовалось в C++ от слова совсем, вот и пихнули свободное относительно подходящее по смыслу ключевое слово. Так что просто повезло, а то сделали бы какой-нибудь __var, и было бы ещё веселее.
Реально проще с нуля новый язык создать, чем это все реанимировать пытаться. D на мой вкус тоже немножко тяжеловат, однако он объективно в 2-3 раза проще пресловутых крестов и код на нем крайне прозрачный.
Автор настолько брутален, что наверно уже побывал в другом измерении и воззрел то, о чем другие не думают. Препроцессор ему мерзкий… что ты вообще на этой грешной земле делаешь?
Поэтому всё будет наихудшим из возможных способов: в С++17 не будет вообще ничего, а вот в следующем стандарте, попомните моё слово, наверняка опять подожмут хвост и с тезисом «нам нужна обратная совместимость» выберут худшее архитектурной решение (экспортировать макросы).
Почему бы не сделать как в rust'е, явную аннотацию для импорта макросов? Т. е. нужны макросы из соответствующего модуля в текущем модуле — написал
[[macro_use]]
и они втащились. И не загрязняет, и возможность есть при необходимости.НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Просто весь аргумент Торвальдса (который скажем, достаточно эпатажен, ну да бог с ним) сводится к "С++ — плохой, потому что на нем говнокодеры могут писать говнокод". Покажите мне язык, на котором невозможно написать говнокод и я вам покажу пример, как это сделать.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
например, Go позиционируется как язык, в котором синтаксически верные конструкции должны образовывать «красивый удобочитаемый и быстрый код». В теории
Вообще-то, Линус утверждает не это, а то, что на C++ написать говнокод легче.
Возмоно все. Вопрос — на сколько тяжело.
"на сколько тяжело" как "язык располагает к плохому коду" или "насколько язык мешает писать плохой код"? Плюсы не мешают писать плохой код: хочешь выстрелить в ногу — пожалуйста. Но и не располагают к этому.
Сколько людей — столько и мнений; всегда найдутся те, кто не любят, когда их язык ограничивает так или иначе.
Сколько людей — столько и мнений; всегда найдутся те, кто не любят, когда их язык ограничивает так или иначе.
Можно сравнить сложность написания хорошего кода и плохого на разных языках. Условно говоря, на C++ хороший код написать проще, чем на чистом C в (условно) 2 раза, а плохой — в 8. Появление большого количества возможностей требует от разработчика большей дисциплины, что бы пользоваться только теми, что нужны и которые сам хорошо понимаешь.
Но хейтить С++ отчасти заставлют такие себе недоученные кнопкожатели, которые кодят не на С++, а на С/С++
Давайте разберёмся: ненавидеть язык программирования С++ Вас заставляют некоторые "недоученные кнопкожатели", которые на этом языке не пишут? Где здесь вообще логика? Это как сказать "я автомобили BMW не люблю, потому что у меня один знакомый на BMW ездил пьяный и убился".
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
N байт на имени класса — это много, когда у вас класс занимает 6 байт и упакова
А зачем хранить имя класса вместе с объектом (ведь 6 байт — это про instance, нет?)
НЛО прилетело и опубликовало эту надпись здесь
Если говорить о скорости, то да, это проблема. С другой стороны, 6 байт фрагментиурет heap.
Почему бы не размещать паразитные указатели по отрицательному смещению, без выравнивания? Так у вас и объект в кеш влезет и операция доступа к TI будет хоть медленной, но доступной.
Почему бы не размещать паразитные указатели по отрицательному смещению, без выравнивания? Так у вас и объект в кеш влезет и операция доступа к TI будет хоть медленной, но доступной.
НЛО прилетело и опубликовало эту надпись здесь
Ну, в таком случае вам и не потребуется сведения о типе в рантайме. Но в случае, когда объекты размещаются и передаются не пачкой, это может быть полезным. Здесь 1 указатель — не такая дикая расплата.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Не только — навскидку — простые serialize unserialize объектов.
НЛО прилетело и опубликовало эту надпись здесь
Для того, чтобы делать все одним и тем же кодом, которому на вход подается объект и строка/буфер. Чтобы не писать и не тащить с собой сериалайзер для каждого типа отдельно.
НЛО прилетело и опубликовало эту надпись здесь
Хм… если у нас есть дочерние классы, то сериалайзер должен работать с родительским — с наиболее общим знаменателем так сказать. Соответственно, если у нас есть класс A, и дочерний B, то сериалайзеру подается cast B в A, т.е. о типе реального B он не знает. Нет?
НЛО прилетело и опубликовало эту надпись здесь
Например — у нас есть, скажем, какой-то экран, форма в некоей нестандартной системе (я описываю реальный случай, но там работа с Delphi производилась, не с С++, но сама ситуация — языконезависима). Виджеты-объекты хранятся в виде списка для этого экрана, соответственно, тип объекта — виджет, а уж кнопка это или editbox какой — науке неизвестно. Теперь мы хотим это все упаковать и перекинуть по сети, а на том конце точь в точь так же развернуть. Итерируем по виджетам, для каждого делаем serialize. Тип неизвестен — он на ходу определяется, для каждого окна свой набор элементов управления.
НЛО прилетело и опубликовало эту надпись здесь
Для этого достаточно каждый виджет наследовать от специального миксина вроде
Как это поможет, например, во время рантайма получить доступ к произвольным полям, которые есть в данном объекте, конкретного класса? Универсальным способом.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Нет, все проще — я очень мало пишу на С++ и не вполне понимаю вашу идею, выраженную в коде. На пальцах — мне нужно установить произвольное поле данных произвольного типа (допустим, не совсем произвольного, а из наперед заданного списка типов данных) в рантайме. Для этого мне надо знать перечень полей данных объекта данного типа(класса) и их типы + методы-обертки для каждого для работы с ними.
Если не писать код сериализации, то придётся прикручивать к классу какие-нибудь атрибуты с метаданными, как в C#, чтобы сказать стандартному сериалайзеру «тут играть, а тут не играть, а это поле вывести под другим именем, а вот это поле даты сконвертировать в такой-то формат, а вот тут у нас конвенция, что если пришёл NULL, то выставь соседнее поле-флаг в false» и т.п. Ибо единой для всех сериализации не бывает.
В итоге сериализационного мусора оказывается столько же, сколько его было бы в специальном классе/методе, только теперь он ещё и разбросан по телу класса вперемешку с полями и методами, и занимает порой больше места, чем само объявление класса. Если хочется одновременно уметь сериализовать в JSON, XML и ProtoBuf, то простой дубовый DTO-класс становится увешан атрибутами, как холодильник магнитиками. Нужно ещё какой-то формат прикрутить? Ура, клеим ещё больше магнитиков! Ну и добавим поверх кучку атрибутов для валидации, или для связывания, или для какого-нибудь маппинга — и наш маленький класс превращается из легковесной структуры данных в непролазную структуру атрибутов.
Хуже того, теперь весь этот мусор приклеен к классу статически, так что единственный доступный способ композиции — через наследование, что резко ограничивает возможности. Скажем, в рантайме детали сериализации отдельного поля не поменять. И есть неприятность: если холодильник абстрактный, то некоторые магнитики (я о тебе, XmlSerializer!) на нём не держатся, поэтому иногда композиция не работает даже через наследование.
Вот так оно обстоит в C#, с рефлексией. После мучений с атрибутами на каждый чих, мне намного интереснее хранить метаданные/метакод рядом, но всё же отдельно — в каких-нибудь классах метаданных с fluent-style-интерфейсом a-la C# FluentValidator или EntityFramework Fluent Mapping API, с возможностью композиции метаданных, с работающим рефакторингом и проч. Отдельно данные, отдельно сериализация, отдельно маппинг, отдельно валидация и т.п., всё можно комбинировать, предоставлять альтернативные реализации, подключать их в рантайме и проч. Хотелось бы, чтобы С++ рос в этом направлении.
В итоге сериализационного мусора оказывается столько же, сколько его было бы в специальном классе/методе, только теперь он ещё и разбросан по телу класса вперемешку с полями и методами, и занимает порой больше места, чем само объявление класса. Если хочется одновременно уметь сериализовать в JSON, XML и ProtoBuf, то простой дубовый DTO-класс становится увешан атрибутами, как холодильник магнитиками. Нужно ещё какой-то формат прикрутить? Ура, клеим ещё больше магнитиков! Ну и добавим поверх кучку атрибутов для валидации, или для связывания, или для какого-нибудь маппинга — и наш маленький класс превращается из легковесной структуры данных в непролазную структуру атрибутов.
Хуже того, теперь весь этот мусор приклеен к классу статически, так что единственный доступный способ композиции — через наследование, что резко ограничивает возможности. Скажем, в рантайме детали сериализации отдельного поля не поменять. И есть неприятность: если холодильник абстрактный, то некоторые магнитики (я о тебе, XmlSerializer!) на нём не держатся, поэтому иногда композиция не работает даже через наследование.
Вот так оно обстоит в C#, с рефлексией. После мучений с атрибутами на каждый чих, мне намного интереснее хранить метаданные/метакод рядом, но всё же отдельно — в каких-нибудь классах метаданных с fluent-style-интерфейсом a-la C# FluentValidator или EntityFramework Fluent Mapping API, с возможностью композиции метаданных, с работающим рефакторингом и проч. Отдельно данные, отдельно сериализация, отдельно маппинг, отдельно валидация и т.п., всё можно комбинировать, предоставлять альтернативные реализации, подключать их в рантайме и проч. Хотелось бы, чтобы С++ рос в этом направлении.
докомпиливать кода на лету
Взять libtcc ;-)
НЛО прилетело и опубликовало эту надпись здесь
В издании Страуструппа, которое я читал, была глава "Правильное и неправильное использование RTTI". В ней было штук пять примеров неправильного, и ни одного правильного применения…
Я не понимаю, зачем в развитом статически типизированном языке с обобщенными типами нужна рефлексия.
Я не понимаю, зачем в развитом статически типизированном языке с обобщенными типами нужна рефлексия.
Если вам нужны доморощеные эксперты по языками — писали бы на паскале или обероне
Воу-воу, палехчи. Паскаль-то чем не угодил?
даже в богомерзком .NET
Мне как .NET разработчику, очень интересно чем же .NET вас так сильно обидел?
А он просто весь неправильный, а так ничего в остальном :)
а что тогда правильное?) И где критерии правильности языков/технологий?)
Критерий правильности — это когда язык\технология делает то, что было положено в основу концепции. К примеру, для С++ это вещи в духе "быть обратно совместимым с С", "быть мульти-парадигменным языком", "быть кроссплатформенным" — и С++, при прочих своих недостатках, придерживается идеологии, заданной изначально. .NET же постоянно предаёт своих почитателей — истории с откуда-то берущимися мемори ликами при вроде-бы отстутствии необходимости управлять памятью, несуществующей обещанной кроссплатформенностью, производительностью, сильверлайтом и ASP.NET, несовместимостью телефонных версий дотнета между собой и с "десктопным" вариантом и т.д. Если С++ идёт своим путём не сворачивая (пусть и медленно), то дотнет плавает туда-сюда вслед за лишним долларом, который компания Microsoft вдруг заметит справа или слева по курсу.
Во многом могу согласиться, однако, справедливости ради приведу некоторые замечания:
1)Memory leak при отсутствии необходимости управлять памятью — это скорее к Java, там нет инструментов для управления памятью, в .NET они есть, хоть и не так сильно развиты, как в С++. Да и скорее всего это вопрос кода, а не самого .NET. "Как написали — так и работает".
2) Кроссплатформенность есть, mono яркий тому пример, да и подвижки есть со стороны Microsoft.
3)Проблема несовместимости заключалась вроде как в разных возможностях самих платформ. Но решение костыльное, да.
Вообще, мотания .NET туда-сюда это не самый лучший путь, и как tangro сказал, особенно если за лишним баксом. Перспективы у платформы отличные, если ее развивать качественно, мудро и серьезно. Впрочем, это про все что угодно относится)
1)Memory leak при отсутствии необходимости управлять памятью — это скорее к Java, там нет инструментов для управления памятью, в .NET они есть, хоть и не так сильно развиты, как в С++. Да и скорее всего это вопрос кода, а не самого .NET. "Как написали — так и работает".
2) Кроссплатформенность есть, mono яркий тому пример, да и подвижки есть со стороны Microsoft.
3)Проблема несовместимости заключалась вроде как в разных возможностях самих платформ. Но решение костыльное, да.
Вообще, мотания .NET туда-сюда это не самый лучший путь, и как tangro сказал, особенно если за лишним баксом. Перспективы у платформы отличные, если ее развивать качественно, мудро и серьезно. Впрочем, это про все что угодно относится)
Дело в том, что любые новые фичи C++ должны пройти через комитет трёх фанатиков.
Первый фанатик обожает исключения. Всё собрание этот ворчливый старик кажется спящим, но в самый неудобный момент вскакаивает и перебивает говорящего криком «и тут мы бросаем исключение!» После этого конечно всё ломается. Этот старик мало кому нравится, но все вынуждены его терпеть.
Второй фанатик обожает шаблоны. Любую фичу он нежно оборачивает в шаблоны, которые заворачивает в шаблоны, которые заворачивает в шаблоны… пока она опять не сломается. В свободное время пытается написать программу по вычислению смысла жизни и вообще на этапе компиляции.
Третий фанатик, самый молодой, обожает всё параллельное. В отличие от других, он не критикует сразу. Он с энтузиазмом хватается за предложенную фичу, сразу переводит его в параллельность, убеждается что всё ломается и со вздохом «в наш век параллельного программирования так делать нельзя» отправляет фичу в корзину. Говорят, у него множество личностей, которые друг перебивают часто друга.
Первый фанатик обожает исключения. Всё собрание этот ворчливый старик кажется спящим, но в самый неудобный момент вскакаивает и перебивает говорящего криком «и тут мы бросаем исключение!» После этого конечно всё ломается. Этот старик мало кому нравится, но все вынуждены его терпеть.
Второй фанатик обожает шаблоны. Любую фичу он нежно оборачивает в шаблоны, которые заворачивает в шаблоны, которые заворачивает в шаблоны… пока она опять не сломается. В свободное время пытается написать программу по вычислению смысла жизни и вообще на этапе компиляции.
Третий фанатик, самый молодой, обожает всё параллельное. В отличие от других, он не критикует сразу. Он с энтузиазмом хватается за предложенную фичу, сразу переводит его в параллельность, убеждается что всё ломается и со вздохом «в наш век параллельного программирования так делать нельзя» отправляет фичу в корзину. Говорят, у него множество личностей, которые друг перебивают часто друга.
По-моему, все не так плохо. Ну или плохо, но виноват не комитет, а авторы предложений, которые не смогли довести их до ума, и остальное сообщество, которое сидело и терпеливо ждало, пока добрые дяди сделают хорошо, вместо конструктивного обсуждения.
string_view же выглядит как затычка, для тех, кто не освоил константные ссылки и shared_ptr
Когда на вход приходит гигабайт текста, который нужно сложным образом обработать, то без string_view есть два варианта — использовать во всех интерфейсах std::string и утонуть в бесконечных копированиях маленьких кусочков, или иметь в интерфейсе функции типа process(const char*, offset, length). string_view есть в бусте под именем boost::string_ref и это life saver.
«Не было консенсуса для принятия».
Унифицированный синтаксис вызова — ну правда же не все так однозначно. Все члены класса начинали бы участвовать в разрешении перегрузок наравне со свободными функциями, как будто сейчас правила разрешения перегрузок недостаточно сложные. Я так понял, что комитет побоялся, что старый код может тихо поменять семантику и продолжить компилироваться, и правильно сделал. Для примера — вот какой оптимистичный тон был у статьи в 2014 году: www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4174.pdf, и что с ней стало через год www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4474.pdf.
Комитет сказал «не готово»
Концепты не готовы. Возможно, спецификация достаточно хорошая, но мы этого не знаем, потому что существующие реализации не позволяют этого проверить, поскольку не умеют практически ничего: они не сообщают, почему именно тип не подошел под концепт, и не проверяют, что в для constrained-типа не используется чего-то, чего нет в концепте. Если вдруг окажется, что реализация этих вещей сопряжена с трудностями, то мы останемся с принятой, но невыполнимой спецификацией (export templates, помните?). Статья на тему: honermann.net/blog/?p=3, дискуссия: www.reddit.com/r/cpp/comments/49b0ph/why_concepts_didnt_make_c17. Обратите внимание на комментарии, где Andrew Sutton, автор спецификации и реализации в GCC, расстроен низкой активностью контрибьюторов:
You guys do know that GCC is an open source compiler. If you had wanted something different, you could have submitted a patch sometime in, say, the last 2 years.
Sadly, few such patches were received. I can count on one hand the number of people who have worked to make the implementation better. I cannot count the number of people who have lined up to throw stones.
string_view же выглядит как затычка, для тех, кто не освоил константные ссылки и shared_ptr
Когда на вход приходит гигабайт текста, который нужно сложным образом обработать, то без string_view есть два варианта — использовать во всех интерфейсах std::string и утонуть в бесконечных копированиях маленьких кусочков, или иметь в интерфейсе функции типа process(const char*, offset, length). string_view есть в бусте под именем boost::string_ref и это life saver.
«Не было консенсуса для принятия».
Унифицированный синтаксис вызова — ну правда же не все так однозначно. Все члены класса начинали бы участвовать в разрешении перегрузок наравне со свободными функциями, как будто сейчас правила разрешения перегрузок недостаточно сложные. Я так понял, что комитет побоялся, что старый код может тихо поменять семантику и продолжить компилироваться, и правильно сделал. Для примера — вот какой оптимистичный тон был у статьи в 2014 году: www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4174.pdf, и что с ней стало через год www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4474.pdf.
Комитет сказал «не готово»
Концепты не готовы. Возможно, спецификация достаточно хорошая, но мы этого не знаем, потому что существующие реализации не позволяют этого проверить, поскольку не умеют практически ничего: они не сообщают, почему именно тип не подошел под концепт, и не проверяют, что в для constrained-типа не используется чего-то, чего нет в концепте. Если вдруг окажется, что реализация этих вещей сопряжена с трудностями, то мы останемся с принятой, но невыполнимой спецификацией (export templates, помните?). Статья на тему: honermann.net/blog/?p=3, дискуссия: www.reddit.com/r/cpp/comments/49b0ph/why_concepts_didnt_make_c17. Обратите внимание на комментарии, где Andrew Sutton, автор спецификации и реализации в GCC, расстроен низкой активностью контрибьюторов:
You guys do know that GCC is an open source compiler. If you had wanted something different, you could have submitted a patch sometime in, say, the last 2 years.
Sadly, few such patches were received. I can count on one hand the number of people who have worked to make the implementation better. I cannot count the number of people who have lined up to throw stones.
Извиняюсь, форматирование цитат пропало.
Чтобы было хорошо, нужно разделить версии стандарта на собственно стандарт языка без библиотек и отдельно сделать стандарт на core библиотекии и разделить циклы их выпуска.
Просто хороший официальный языкоспецефичный пакетный менеджер нужен, как у белых людей.
Я тут недавно думал, а ведь если в cargo добавить ещё несколько команд типа upgrade, uninstall и добавить поддержку репозиториев, то можно сделать его и не языкоспецифичным.
uninstall уже есть. Реп пока нет, но чего-то с зеркалами crates.io потихоньку делают — думаю, в репы в итоге выльется.
Лично мне бинарных зависимостей недостает :(.
> можно сделать его и не языкоспецифичным.
Да не, он слишком сильно к rustc привязан, как в исходниках, так и на уровне аргументов команд. Для других языков почти весь переписывать придется.
Лично мне бинарных зависимостей недостает :(.
> можно сделать его и не языкоспецифичным.
Да не, он слишком сильно к rustc привязан, как в исходниках, так и на уровне аргументов команд. Для других языков почти весь переписывать придется.
Вместо UCS надо было сделать просто class helpers и всё.
В комментах все хоронят С++, а на практике большинство или продолжает им пользоваться, или никогда его не использовало.
Имхо, единственный конкурент С++ — это Rust, и пока непонятно взлетит он или нет, хотя шума удалось наделать немало. Вполне возможно, что он останется уделом маргиналов, как D…
Имхо, единственный конкурент С++ — это Rust, и пока непонятно взлетит он или нет, хотя шума удалось наделать немало. Вполне возможно, что он останется уделом маргиналов, как D…
>>Специальные математические функции
>>Что-что вы решили добавить в язык?! Сферические гармоники и гипергеометрические функции?
Странная ирония. Матаматика используются в большом количестве проектов. CAD и EDA системы, моделирование и т.п. Даже просто для обучения студентов гораздо проще использовать встроенные вещи.
>>Что-что вы решили добавить в язык?! Сферические гармоники и гипергеометрические функции?
Странная ирония. Матаматика используются в большом количестве проектов. CAD и EDA системы, моделирование и т.п. Даже просто для обучения студентов гораздо проще использовать встроенные вещи.
Предложить стандарт для менеджера библиотек и все специальное переместить туда не было бы правильнее?
Резонное замечание. Может быть тогда вы и сможете написать proposal стандарта на пакетный менеджер и предложите его комитету?
Кстати, увидел сегодня статью «NPM и left-pad: мы разучились программировать?» https://habrahabr.ru/post/280099/, цитата из неё:
«Функции слишком малы, чтобы попасть в пакет и зависимость. У чистых функций нет связи; это случайные фрагменты кода и ничего больше. Кому нужна зависимость от косинуса? Вместо этого нам бы по-настоящему понравилась зависимость от пакета «тригонометрия», который охватывает много хитрых функций, которые мы не хотим писать сами. Это гораздо больше похоже на то, как .NET и другие фреймворки создают базовую библиотеку с основной функциональностью. Такая библиотека проверена создателями языка и обладает в значительной степени гарантированной надёжностью, с отсутствием багов».
Мне кажется, что это как раз тот случай. Т.е. намного приятней, когда есть стандартная математическая библиотека есть во всех реализациях языка и ведёт себя одинаково.
«Функции слишком малы, чтобы попасть в пакет и зависимость. У чистых функций нет связи; это случайные фрагменты кода и ничего больше. Кому нужна зависимость от косинуса? Вместо этого нам бы по-настоящему понравилась зависимость от пакета «тригонометрия», который охватывает много хитрых функций, которые мы не хотим писать сами. Это гораздо больше похоже на то, как .NET и другие фреймворки создают базовую библиотеку с основной функциональностью. Такая библиотека проверена создателями языка и обладает в значительной степени гарантированной надёжностью, с отсутствием багов».
Мне кажется, что это как раз тот случай. Т.е. намного приятней, когда есть стандартная математическая библиотека есть во всех реализациях языка и ведёт себя одинаково.
npm — не самый удачный пакетный менеджер. Если удаление пакета будет запрещено, будут соблюдаться соглашения "семантических версий" (например, менеджер пакетов языка elm проверяет, что при изменении минорной версии сигнатуры функций не меняются) и публикация новой версии возможна только после прохождения тестов — таких проблем не будет.
На мой взгляд уже и 11 стандарт был «давайте включим десяток общепризнаных библиотек в стандарт» ну и добавим немножко сахарку типа тех же auto и rvalue. Каких то принципиальных нововведений в сам язык нет и похоже не предвидится, а жаль. Меня например бесит отсутствие инкапсуляции как таковой. Ну пишу я класс, сделал член класса приватным. У него какой то хитрый тип, который клиентам знать не нужно да и не положено, но будь добр ввальни инклюдничек с этим хитрым классом, а не хочешь инклюдничек этот тащить тогда посди поизвращайся либо с указателями, либо интерфейсики рисуй… В итоге код обрастет ненужными классами и интерфейсами, потом все дружно на это забивают и до свидания, инкапсуляция.
Тут как раз всё логично, на системном уровне по другому инкапсуляцию не сделаешь, или ты видишь кишки или ты видишь указатель на кишки, где может быть что угодно. Просто здесь уж слишком в лоб всё сделано и синтаксис не помогает красиво всё разруливать.
Я сейчас выскажу свое ощущуние, но обилие книг «как правильно писать на языке с/с++» да и обилие комментариев даже в этой теме по шаблону «с/с++ программисты не умеют правильно использовать имеющиеся средства языка» придает ощущение, что что-то неправильно в консерватории, и комитет от 11 стандарта к 17 стандарту увы это не упрощает. Еще больше стандартных библиотек, еще больше описания в стандартах, еще больше UB. Мне кажется монографию Страуструпа «Язык С++» пора уже делать многотомником.
Ещё может быть буфер размером аккурат с те самые кишки, о содержимом и структуре которого только кишки и знают.
Костыльнуть можно уже сейчас, через aligned_storage. Но это конечно же именно костыльнуть.
Костыльнуть можно уже сейчас, через aligned_storage. Но это конечно же именно костыльнуть.
У комитета просто временный аналитический паралич.
даже в богомерзком .NET
Зачем делать вбросы, тем более в корпоративном блоге? Откуда этот tech-нацизм? Так сложно просто сослаться на технологию, с которой у Вас не сложилось?
(p.s. для справки, 5 лет разрабатывал на С++, 5 лет на C#, понимаю их достоинства и недостатки, и камней в огород этих зрелых и мощных экосистем кидать не собираюсь)
Я не знаю как всё там в комитете варится внутри
Через постель!
НЛО прилетело и опубликовало эту надпись здесь
Вы непоследовательны
Я имел в виду, что параллельность — это нечто, что может быть во внешних библиотеках, поскольку имеются различные подходы к её построению — распараллеливание отдельных алгоритмов, пулы потоков, воркеры, таски в духе TBB — и аж до MPI. Ни один из этих подходов никогда не станет "единственным правильным". С другой стороны, протоколы TCP и UDP (да и HTTP) — это уже довольно устоявшиеся вещи, для них может существовать эталонная реализация в стандартной библиотеке, как она существует в некоторых других языках.
С немножко разных контекстов auto и инстансов шаблонов.
Я тут читаю последнюю книгу Мейерса, где он рассказывает о выводе типов в auto — так вот по его словам это один-в-один тот же вывод типов, что и для шаблонов. Есть полтора исключения, которые на практике всем кроме разработчиков компиляторов можно игнорировать.
В хаскеле «уже давно»
В хаскеле много чего "уже давно", что в С++ мозги сломает в два счёта.
Это как раз наилучший способ
Мне тяжело принимать парадигму, в которой "не сделать никак" может быть лучшим способом. С обоими предложениями можно мириться, оба имеют реализацию, проголосовать какое лучше — да и всё на этом. Всё-равно принципиальный вопрос с макросами никуда не денется и решить его можно только голосованием — или так, или так.
Ошибка компиляции лучше, чем ошибка в рантайме
Только если для этого не нужно переписать половину программы а всяких забавных шаблонных фокусах и constexpr-магии. Такое себе программирование ради программирования, а не ради практических задач.
Я сделал memory mapped file...
Личто я привык в подобных случаях объявлять структуры, описывающие, например, заголовок файла и мапить их на блоки данных в памяти. А уже имея описание структуры, можно всё что хочешь делать — и удобно доступаться к данным, и константные ссылки туда-сюда гонять и т.д. Да, string_view удобный синтаксический сахар именно для непрерывных диапазонов, но какой-то революции здесь нет, кому надо — гонял себе пары итераторов или указатель+размер и я бы не сказал, что это давало какой то оверхед, или было нечитаемо, или вело к ошибкам.
static_assert(AddEleven(5)==16,"");
Раз уж речь о C++17, то
static_assert(AddEleven(5)==16);
Как то пессимистично у вас все написано. Самое интересное, вы сами понимаете почему комитет так осторожничает. Все не так плохо.
А есть все-же шанс что комитет изменит свое мнение? Еще до 17 года достаточно времени…
Пропустил пару сезонов, и уже ничего не могу понять. Напомните, в языке системного программирования C++ уже появился тип `byte`?
Этот тип присутствует там с момента появления языка и называется [un]signed char. Вы, похоже, действительно много пропустили, если этого не знаете.
Почему тогда переменная b ни в отладчике, ни в консоли не отображается как «C9», а отображается как «b = 201 'É'» и «╔» соответственно?
unsigned char const b = 0xC9;
std::cout << b << std::endl;
unsigned char const b = 0xC9;
std::cout << b << std::endl;
НЛО прилетело и опубликовало эту надпись здесь
Да я знаю, что тут происходит, это был риторический вопрос. Просто то, что я наблюдаю в оnладчике и в консоли, никак не могу назвать «тип `byte` присутствует там с момента появления языка». Даже в C# перемалывать байты приятнее, чем в языке системного программирования C++.
gcc
http://coliru.stacked-crooked.com/a/f92ac597e8b6308e
$ cat p.cxx
#include <iomanip>
#include <iostream>
int main()
{
unsigned char const b = 0xC9;
unsigned char const a[] = { 0xA, 0xC0, 0xC9};
std::cout << std::hex;
std::cout << +b << std::endl;
for (auto it : a) {
std::cout << +it << std::endl;
}
}
$ g++ -Wall -Wextra -ggdb3 p.cxx -o p
$ ./p
c9
a
c0
c9
$
gdb session
$ cat p.cxx
#include <iomanip>
#include <iostream>
int main()
{
unsigned char const b = 0xC9;
unsigned char const a[] = { 0xA, 0xC0, 0xC9};
std::cout << std::hex;
std::cout << +b << std::endl;
for (auto it : a) {
std::cout << +it << std::endl;
}
}
$ g++ -Wall -Wextra -ggdb3 p.cxx -o p
$ gdb ./p
Reading symbols from ./p...done.
(gdb) b main
Breakpoint 1 at 0x40089e: file p.cxx, line 6.
(gdb) r
Starting program: /tmp/p
Breakpoint 1, main () at p.cxx:6
6 unsigned char const b = 0xC9;
(gdb) n
7 unsigned char const a[] = { 0xA, 0xC0, 0xC9};
(gdb)
9 std::cout << std::hex;
(gdb) p/x b
$1 = 0xc9
(gdb) p/x a
$2 = {0xa, 0xc0, 0xc9}
НЛО прилетело и опубликовало эту надпись здесь
Ну, исторически байт — это символ. Он даже состоит из 8 бит именно поэтому. Вводить ещё один синоним в стандарт только для красоты странновато.
НЛО прилетело и опубликовало эту надпись здесь
Я знаю чем отличается октет от байта. Я имел в виду, что размер байта для первых машин был либо 7 либо 8 бит именно по тем соображениям, что столько бит достаточно, чтобы закодировать один символ. По-крайней мере, так нам рассказывали в ВУЗе. А значит исторически байт и символ — сущности крайне близкие. Само собой, потом понятия разошлись и сейчас не редки случаи, когда тип char в тех или иных языках может достигать размера 4 байт, а в спецификациях всех мастей используется термин "октет" означающий 8 бит, для того чтобы не привязываться к конкретным архитектурам.
И кстати, да, по стандарту C (не POSIX, а самого языка) sizeof(char) == 1.
И это довольно очевидно, потому что в стандарте нет другого типа, который мог бы исполнять роль байта.
C99, section 6.5.3.4:
When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1.
И это довольно очевидно, потому что в стандарте нет другого типа, который мог бы исполнять роль байта.
Этот тип присутствует там с момента появления языка и называется [un]signed char. Вы, похоже, действительно много пропустили, если этого не знаете.
Зачем же его тода опять пытаются добавить в C++ как std::byte
, раз он по-вашему там с момента появления языка? Авторы Стандарта тоже многое пропустили?
НЛО прилетело и опубликовало эту надпись здесь
Очевидно, этот алиас не повлияет на код из примера выше:
std::uint8_t const b = 0xC9;
std::cout << b << std::endl;
std::uint8_t const b = 0xC9;
std::cout << b << std::endl;
Если Вам мало системности и байтовости, то вот вам битовость:
Доступ к битам в комплекте.
bitset<8> set1("11001111");
bitset<8> set2(0xC9);
cout << hex << set1.to_ulong() << set2.to_ulong() << endl;
Доступ к битам в комплекте.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
И gcc gdb, и clang lldb поддерживают pretty-printers, благодаря которым можно что угодно как угодно печатать.
rust
$ cat hello.rs
fn main() {
let opt = Some(4);
let v = vec![1, 2, 3, 4, 5];
println!("{:?} {:?}", opt, v);
}
$ rustc hello.rs -g
$ rust-gdb hello
Reading symbols from hello...done.
(gdb) b hello::main
Breakpoint 1 at 0x557d: file hello.rs, line 2.
(gdb) r
Starting program: /tmp/hello
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Breakpoint 1, hello::main () at hello.rs:2
2 let opt = Some(4);
(gdb) n
3 let v = vec![1, 2, 3, 4, 5];
(gdb)
5 println!("{:?} {:?}", opt, v);
(gdb) p opt
$1 = Some = {4}
(gdb) p v
$2 = Vec<i32>(len: 5, cap: 5) = {1, 2, 3, 4, 5}
(gdb) p/x opt
$3 = Some = {0x4}
(gdb) p/x v
$4 = Vec<i32>(len: 5, cap: 5) = {0x1, 0x2, 0x3, 0x4, 0x5}
C++17, который мы потеряли