company_banner
24 августа 2015 в 20:15

Настоящее и будущее C++. Интервью с Эриком Ниблером

Эрик Ниблер — известный эксперт по C++, один из важных контрибьюторов Boost, человек, который добавил в стандарт библиотеку Ranges.

26 августа в рамках C++ Party Эрик выступит в новосибирском офисе Яндекса, где как раз расскажет о библиотеке и поговорит с гостями о новых стандартах C++.

image

Я заранее поговорил с Эриком и задал ему несколько вопросов от себя и коллег о том, каким он видит настоящее и будущее C++, что ему кажется самым важным в программировании, будет ли в C++ когда-нибудь нормальный менеджер пакетов, модули, что будет со стандартной библиотекой и о многом другом.

Кстати, если у вас есть ещё хорошие вопросы к Эрику, — их можно задать в комментариях, и мы попросим его на них ответить.

Оригинал для тех, кто предпочитает читать по-английски (увы, по-русски Эрик пока не говорит)
How did you start to code on C++? Do you write code by yourself (boost and stl not counted) or just consult?

I learned C++ as an undergraduate student at the University of Virginia. It was actually required back then.Writing code is like breathing or eating for me. If I didn't do it daily, I would die. Find me on github to see what I'm working on this week.

What would you most likely advise to be changed in the language? Were there any wrong decisions in the C++ history? What would you change in the language if you could?

I don't have many complaints about the language, but there is a major shortcoming in the Standard Library that I would like to see changed: it's way too small. C++ is a great language for building libraries. We just need more.

What should be improved in C++ first?

There's really so much: compile times, better support for Generic Programming, reflection, ranges, Unicode support, etc, etc. But if I had to pick the one things that would transform the C++ world the most, I would say an easy-to-use, robust, powerful, and flexible package
manager. Finding, downloading, compiling, and installing libraries — with all their dependencies at the correct versions — is just way too hard today.

What do you think about C++ Standards Committee? Does it do a good job? Or is it too slow or conservative in some respect?

As a long-time member of the Committee, I probably have a different perspective on this than most. Design-by-committee happens. Catering to the experts happens. Solving small, isolated problems while ignoring larger systemic issues happens. But on the whole, I think the committee does a good job for what it is: a group of volunteers. And the «release cadence» has picked up dramatically since C++11. It's a full-time job to keep up with it all. It's exciting to be a part of it.

Do you think that if there were one person or someone esle who would be making all of the decisions — like W3C — it would be better, or is the Committee a good compromise?

Better in some ways, worse in others. I've occasionally wondered if C++ would be better with a BDFL like Python has in Guido. When the committee has to choose between two incompatible designs for a feature, it sometimes chooses both and adds a third option. That's bad. The alternative is to trust one person to have the good judgement to pick the «right» solution. But nobody chooses right every time. Distributing the decision making adds a crucial sanity check before ideas get baked into an International Standard. I know my work is vastly better for having to run them through the committee gauntlet. It's grueling, but C++ as a whole is better for it, IMO.

Is there any chance that some day a version of C++ with little or no backward compatibility will be released?

I don't see that happening ever, no. In the library perhaps, but not in the language.

What is your favourite code language after C++?
For simple scripting stuff, I reach for Python. Every now and then I poke at Haskell a bit. I like the rigor and math-y-ness. It's fun to puzzle out how things work in that language, but I'm not proficient enough to be productive yet.

Do you always understand multi-page errors that you get when using Boost?
Not right away, no.

Does it worries you that using Boost makes compiling manyfold slower for some projects?

Absolutely. I can haz modules? :-)

Do you use exceptions in your C++ code?
I write exception-neutral code (exceptions can pass through harmlessly), but I don't often write code that throws exceptions. In my way of thinking, exceptions are only for runtime failures: when the state of the world disagrees with the state of a program. As a library developer, I don't often interact directly with the outside world. (It's messy out there.) I am primary concerned with the internal consistency of programs. E.g., has this API been called incorrectly? For those sorts of errors (so-called logic errors), I use assertions.

When you look at your code after time do you like it or want to rewrite?
I usually like it and I want to rewrite it. Library redesign is the most important part of library design.

If you had to name one or two changes in the C++11/14 Standard that are the most important, which ones would you choose?

Again, my perspective is skewed here by my role as a library developer. I feel that decltype was the most sorely needed feature before C++11. When I look back on all the ugly hacks in Boost to work around the lack of decltype, I am deeply grateful that we don't have to live like that
anymore.

The same question, but about the most controversial changes. Is there something that can have a negative effect?
Certainly: rvalue references. They're powerful, but they're just too hard to use correctly, and too easy to use incorrectly. My style has evolved such that I use them very sparingly and only in ways that I can feel confident about.

Noexcept gets honorable mention here. Not even the Committee can agree on how and where to use it.

How to deal with the complexity of the language?
Program in the «modern» subset. It's possible to write clean, simple, beautiful C++ code these days.

As for evolving a complex language like C++: Make changes that increase uniformity (see: uniform initialization) and give people simpler, safer ways to do complicated, error-prone things (see: auto, range-for, smart pointers). Deprecate the bad stuff (see: throw specifiers, auto_ptr). Write tools that help people program in the modern subset (see: clang modernize).

C++ is sometimes criticised for being a very discrete and abstract, almost Spartan, Standard Library. It doesn’t have a variety that other modern languages have. Do you think this is the right approach?

Absolutely not! The criticism is fair: the Standard Library needs to be greatly expanded. I want: Unicode support, databases, date/time support, serialization, networking (with support for lots of different protocols), parsing, etc., etc. The list is endless.

Creators of the original standard library think that it should be small and atomic, and everything else should be in a different library, not in the language itself. Do you think that this should be the case?

Who says this? I have never heard this view espoused in the Committee. Folks there are eager to expand the Standard Library.

Many people are asking for some standard repository like in some other languages. What do you think about this? Is there a need for it and how soon the C++ community can make it possible?

YES. Together with tooling, it's the biggest obstacle to adoption C++ has today, IMO. Some clever folks have tried to solve this problem, with limited success to date. It would take Microsoft or a Google (or a Yandex?) to really fix this, I think. It's the kind of hard, boring,
inglorious work that tends not to get picked up by volunteers.

Many people may think that C++ is terrible, actually, but they’re still using it, and it’s the main language used in their development. How do you think the decision should be made about what language to use in a large projects?

C++ is a very good language for large-scale projects, and projects where performance and footprint matter. I wouldn't pick C++ for a simple scripting task. It's all about picking the right tool for the job.

Do you think that it’s bad for C++ that it’s rarely used on mobile devices? All these new things use managed languages. Java for Android, Objective C and Swift for iOS. What do you think about that and couldn’t C++ be used more efficiently for these applications.

I'm dumbfounded that C++ isn't used more heavily on mobile. These are resource-constrained devices. Why pay for a VM?

These days, I'm hearing a bit more about teams writing the bulk of their mobile application logic in C++ for the sake of portability. The prospect of maintaining parallel codebases in different languages is just too awful to consider. It's a «well duh» that's been a long time
coming.

What do you think about Rust?

I've heard some positive buzz, but I haven't looked into it.

What is your favorite C++ IDE?

Visual Studio, hands down. I haven't tried CLion yet, but Eclipse was too awful for words the last time I tried it (which admittedly was a long time ago). Emacs/vim/gdb feels like banging rocks together when the rest of the world is at cruising speed. (Cue the angry trolls telling me what a Luddite I am for disparaging Emacs/vim/whatever.)

How did you convince the Committee that the Ranges library is important?

I got the job by volunteering to do the work, I think. The Committee was ready to say yes to just about any coherent Ranges proposal. There was an almost audible sigh of relief when I first presented my work.

Some developers think that C++ include too much poorly compatible features, that language is exaggerated. Do you share their opinion? If you were creating a language from scratch which existing features you would not have included? Is there a chance that some parts of modern C++ in the future will be declared obsolete and deprecated?

Parts of C++ have already been declared deprecated (throw specifiers) and some have actually been removed (export templates and auto as a storage specifier). I won't argue that C++ has warts. It does. Some are from it's C legacy, like the declaration syntax. Some are from standardizing features we didn't have enough experience with (allocators), and some are just bloated and poorly designed (iostreams, locales, string). I've never seen a compelling use case for virtual inheritance (OK, I use it in my own code for simulating Concepts, but I look forward to a time when it's not needed). I think inheritance is grossly overused. I would de-emphasize that feature and provide a clean, simple way to achieve dynamic polymorphism with value semantics (see: Sean Parent, «Inheritance is the Base Class of Evil»).

I would love to see the preprocessor go away. Other languages have awesome tooling support that is hard or impossible in C++ because of the preprocessor. In it's place, I would prefer an AST-based, hygenic macro processor. Let me manipulate my program's AST at compile time. I'll never need to do token pasting ever again.

What is more important for you: aesthetics (to make language or ibrary more beautiful, elegant) or practice (to make it more useful for daily tasks)? If the answer is practice, what daily tasks come into your mind first of all?

Aesthetics are important, but if I thought that was the most important thing, I'd program in Haskell. That said, I think «aethetics vs. practicality» is a false dichotomy. It's possible to have both, and I think the modern style of C++ is quite close.

The daily tasks that matter to me are the ones that come up again and again in every program of every scale in every domain: writing and calling ALGORITHMS and reasoning about their complexity, efficiency, and correctness. This is what programming is about. Making C++ better in this regard is what gets me out of bed. It has to be efficient, and it has to solve real-world problems. But it also has to be elegant. Elegant code is easy to write, easy to read, easy to use correctly, and hard to use incorrectly. Elegant code is a joy to use. If I can make the day-to-day lives of C++ programmers more fun, then I've done my job.


Расскажите, как вы начали программировать на C++? Вы ещё пишете код сами (boost и stl не считается) или только консультируете?

Я выучил C++ студентом, когда учился в Университете Вирджинии. Он был обязательным предметом. Для меня писать код — это как дышать или есть. Если я не буду этим заниматься каждый день, умру. Можете посмотреть на моём гитхабе, чем я занимаюсь на этой неделе.

Если бы вы создавали C++ с нуля, что бы вы сделали по-другому?

У меня немного жалоб на язык, но в Стандартной библиотеке есть важный недостаток, который бы я хотел исправить — она слишком маленькая. C++ — отличный язык для создания библиотек. Их должно быть больше.

В каких направлениях в первую очередь стоит улучшать C++?

Их не так уж и много: время компиляции, улучшение поддержки для обобщённого программирования, reflections, ranges, поддержка юникода и так далее и тому подобное. Но, если бы мне нужно было выбрать всего одну штуку, которая больше всего повлияла бы на C++, я бы выбрал простой, надёжный и мощный менеджер пакетов. Искать, загружать, компилировать и устанавливать библиотеки со всеми их зависимостями слишком сложно сейчас.

На ваш взгляд, Комитет по стандартизации достаточно эффективно выполняет свою работу?

Поскольку я давний член Комитета, моя точка зрения на этот вопрос, вероятно, отличается от обычной. Иногда бывает «разработка коммитетом», когда у семи нянек дитя без глаза. Иногда узкие проблемы решают без системного подхода. Но в целом мне кажется, что Комитет свою работу делает хорошо, особенно для своего формата, а это формат группы волонтёров. И ритмичность релизов значительно улучшилась, особенно после C++11. Просто оставаться в курсе всего происходящего — работа с полной занятостью. Я рад быть частью этого.

Возможно, было бы лучше, если бы был один человек, который отвечает за ключевые решения?

С одной стороны, лучше, но с другой — хуже. Я иногда раздумывал, не было бы лучше, если бы у C++ был свой просвещённый диктатор, как Гвидо у Python. В случаях, когда комитету нужно выбрать между двумя несовместимыми видами какой-то фичи, иногда он выбирает оба и ещё добавляет третью опцию. Это плохо. Альтернатива — довериться одному человеку, чтобы он всегда делал «правильный» выбор. Но никто не выбирает правильно в ста процентах случаев. Разделение такого решения на нескольких человек значительно уменьшает вероятность пропустить что-то плохое через Комитет. Я уверен, что моя работа становится лучше от того, что приходится проходить пекло Комитета. Это изматывающе, но C++ от этого на мой взгляд выигрывает.

Как вам удалось убедить комитет в необходимости библиотеки Ranges?

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

Некоторые разработчики полагают, что С++ содержит слишком много разных плохо совместимых друг с другом возможностей, что язык «раздут». Разделяете ли вы это мнение? Если бы вы проектировали язык С++ заново, с нуля, какие существующие возможности вы бы в него не включили? Есть ли шансы, что какие-то части современного нам С++ в будущем будут объявлены устаревшими и не рекомендуемыми к использованию?

Кстати, части С++ уже объявлены устаревшими (throw specifiers), а некоторые уже убрали из стандарта (export templates и auto как спецификатор хранения переменной). Я не буду спорить, что в C++ есть свои уродства. Конечно, есть. Некоторые — наследство от C, вроде синтаксиса деклараций. Некоторые от добавления в стандарт фич, в работе с которыми у нас ещё не было достаточного опыта (аллокаторы), и некоторые просто были плохо спроектированы и раздуты (iostreams, locales, string). Я ни разу не видел ситуацию, где было бы оправданно использование виртуального наследования (ОК, я сам его использовал, чтобы эмулировать Concepts, но надеюсь, что в будущем этого будет не нужно). Я думаю, наследование используют слишком часто. Я бы убрал с него акцент и предоставил простой и понятный путь для динамического полиморфизма с value semantics (читайте «Наследование — базовый класс всех зол» Шона Парента).

Я рад был бы застать момент, когда препроцессор уйдёт в прошлое. У других языков есть очень крутые инструменты, которые невозможно реализовать в C++ из-за существования препроцессора. Я бы предпочёл на его месте основанный на AST чистый макропроцессор. Позвольте мне управлять AST моей программы во время компиляции. И мне никогда больше не понадобится вставлять или заменять что-либо.

Есть ли шанс, что в какой-то версии С++ не будет обратной совместимости, как было с некоторыми другими языками?

Не думаю, что такое случится, нет. Может, отдельные библиотеки, но точно не стандарт языка.

Какой у вас любимый язык программирования после C++?

Для простых скриптов я использую Python. Иногда экспериментирую с Хаскеллом. Я люблю строгость и математичность. Прикольно бывает разбираться, как там устроены какие-то вещи, но моего опыта недостаточно, чтобы делать что-то серьёзное.

Когда вы используете Boost, часто ли бывает такое, что вы с трудом понимаете многостраничное сообщение от компилятора?

Не всегда.

Не расстраивает ли вас, что, если подключить к проекту библиотеку Boost, время компиляции замедляется в разы?

Конечно. Когда уже будут модули? :-)

Используете ли вы исключения, когда пишете на C++?

Я обычно пишу код, который exception-neutral (такой, который не влияет на чужие исключения), но довольно редко я выбрасываю исключения из своего кода. Моё понимание жизни такое: исключения надо использовать только для поломок в рантайме, когда устройство мира не совместимо с состоянием программы. А как разработчик библиотек я довольно редко взаимодействую с миром вовне (там слишком большая суматоха.) В первую очередь я сосредоточен на консистентности внутреннего устройства кода. Например, корректно ли вызвали этот метод API? Для такого типа ошибок (их называют логическими) я использую assertions.

Когда вы просматриваете свой код по прошествии времени, он вам нравится или вы хотите его переписать?

Он мне нравится, и я хочу его переписать. Переконструирование библиотек — самая важная часть их конструирования.

Что бы вы хотели увидеть в новом стандарте C++? Какую фичу C++ вы считаете самой вредной и самой полезной?

Повторю, что на мой взгляд здесь сильно влияет то, что я разработчик библиотек. Мне кажется, что decltype были самой отчаянно нужной фичей до появления C++11. Когда я вспоминаю все те кривые костыли, которые пришлось использовать в Boost, чтобы обойтись без decltype, я немедленно становлюсь очень-очень благодарен миру, что нам так больше делать не придётся. Если говорить, об изменениях, которые имели негативный эффект, то совершенно точно это rvalue ссылки. Они очень мощные, но их очень сложно использовать правильно и слишком легко — неправильно. Я сам научился использовать их строго только в тех случаях, в которых я абсолютно уверен.

Не могу не упомянуть ещё noexcept. Даже участники комитета не могут договриться о том, как и где их правильно использовать.

У вас есть совет, как бороться со сложностью языка?

Программируйте только на современном подмножестве языка. В наше время можно писать чистый, понятный и красивый код на C++.

Что до развития в таких сложных языках, как C++ — изменяйте старый код так, чтобы улучшать единообразность кода (см. единообразную инициализацию), и делайте так, чтобы у людей была возможность просто и безопасно делать сложные вещи, в которых легко ошибиться (см. auto, range-form, умные указатели). Переставайте использовать устаревшее (см. auto_ptr, throw specifiers). Создавайте инструменты, которые помогут людям разрабатывать на современном подмножестве языка (см. clang modernize).

C++ часто критикуют за слишком краткую и абстрактную, почти спартанскую стандартную библиотеку. Нет такого разнообразия, как в некоторых современных языках. Вы считаете такой подход правильным?

Точно нет! Критика справедлива: Стандартная библиотека должна стать больше. Я хочу поддержку Юникода, баз данных, date/time, сериализацию, сетевой стек (с поддержкой большого количества разных протоколов), парсеры и т.п. и т.д. Список бесконечен.

Авторы STL считали, что стандартная библиотека должна быть маленькой и атомарной. Это одна из причин того, что в ней нет некоторых базовых для нашего времени вещей. Что вы думаете об этом?

Кто так говорит? Я никогда не слышал, чтобы такое мнение кто-то высказывал в Комитете. Все готовы расширять стандартную библиотеку.

Нужен ли С++ единый репозиторий?

ДА. Помимо нехватки удобных инструментов, я считаю это главным препятствием к ещё более широкому распространению C++ сейчас. Несколько умных парней уже пытаются эту проблему решить, но пока с переменным успехом. Мне кажется, для её решения, возможно нужен гигант вроде Майкрософта, Гугла (или Яндекса?). Это сложная, большая, занудная и не приносящая славы задача того типа, которыми не любят заниматься волонтёры.

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

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

Плохо ли, что C++ редко используется на мобильных устройствах? Все они по-прежнему работают на управляемых языках: Java — на Android, Objective-C и Swift — на iOS. Не пора ли более активно применять C++ в этой области?

Меня шокирует то, что C++ не используют в мобильной разработке активнее. Там же устройства с ограниченными ресурсами. Зачем тратиться на виртуальную машину?

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

Что вы думаете о Rust?

Я слышал о нём хорошие слова, но подробно не разбирался.

В какой IDE вы предпочитаете работать с C++?

Лёгкий вопрос: Visual Studio. Я не пробовал пока CLion, но Eclipse в последний раз, когда я им пользовался (довольно давно, надо признаться), был ужасен настолько, что и словами не описать. Использовать emacs/vim/gdb — это как пытаться каменными инструментами сделать колесо в то время, как остальной мир давно ездит по автострадам. (Да, это вам, злые тролли, которые говорят мне, что моё пренебрежение к emacs/vim — признак луддита.)

Что для вас важнее в вашей работе: эстетика (сделать язык или библиотеки красивее, стройнее) или практика (сделать их удобнее для повседневных задач)? Если второе, то какие задачи вам приходят в голову прежде всего?

Эстетика важна, но6 если бы я считал её самой важной штукой в мире, я бы программировал на Хаскелле. Имея это в виду, я думаю, что «эстетика против практичности» — ложная дихотомия. Можно иметь и то, и то. И мне кажется, что современный стиль программирования на C++ к этому нас очень приближает.

Каждодневные задачи, важные для меня — это те, что встречаются вновь и вновь в каждой программе любого уровня и по любой теме: написание и использование АЛГОРИТМОВ и размышления над их сложностью, эффективностью и корректностью. Программирование именно про это. Сделать C++ лучше применимым для этого — то, что поднимает меня каждое утро. Язык должен быть эффективным, должен решать задачи из реального мира. Но он должен быть и элегантным. Элегантный код легко писать, легко читать, легко корректно использовать и сложно использовать некорректно. Элегантный код доставляет удовольствие, когда его используешь. Если я смогу добавить удовольствия в каждодневную жизнь разработчиков на C++, я буду считать свою работу сделанной.

PS: На мероприятие ещё можно зарегистрироваться. Также можно прийти в офисы Яндекса в Нижнем Новгороде, Екатеринбурге и Минске, чтобы поучаствовать в телемосте и задать свои вопросы Эрику. Для тех, кто не сможет до нас дойти, мы организуем трансляцию, которая будет доступна здесь. Начало трансляции — 16:00 по московскому времени (19:00 — по новосибирскому).
Автор: @anton
Яндекс
рейтинг 1 065,81
Как мы делаем Яндекс
Похожие публикации

Комментарии (97)

  • +2
    Его троллфейс так и говорит: никогда!
    • +16
      Использовать emacs/vim/gdb — это как пытаться каменными инструментами сделать колесо
  • +3
    эх… а я надеялся, что он то уж точно знает, когда будут модули
    • 0
      А вот лично меня устраивает деление на заголовочники и cpp файлы, мне нравится препроцессор и абсолютно не понятны пассажи к переделки этих удобных вещей.
      • +9
        деление на заголовочники и cpp файлы это еще не самое страшное зло. Самое страшное зло — это отсутствие такого деления в свете шаблонов)))
      • +4
        Время компиляции вас тоже устраивает?
        • +1
          Человек просто не пробовал скомпилить большой проект, больше миллиона строк на Delphi и на С++ =) Я обеими руками за модули, и уже смотрел как их в Clang реализовали.

          p.s. по-моим прикидкам «на глаз», разница в скорости сборки в сотни, если не тысячи раз.
          • +2
            Так, для справки:
            Наши проекты на Delphi (1.5 и 1.8 млн строк) компилируются за 38 и 18с соответственно (разница из-за разницы в сложности связей) на холодном кеше, и это полный ребилд. Если компилировать только измененные модули + линковка, вообще мгновенно, секунд 5-7.
          • +2
            Delphi компилятор на порядок быстрее любого сишного, уж извините
            • 0
              Это интересно, расскажите подробнее, в чём причины такой высокой скорости компиляции Delphi? Сам язык значительно проще или есть и другие существенные факторы?
              • +2
                Сам язык. Тот же Паскаль, а он изначально под однопроходку создавался. Ну и откровенно говоря, оптимизатор у него слабоват.
                • 0
                  Из-за однопроходности в delphi/lazarus например нельзя сделать так:
                  type TFunctionChain = function(const value: String): TFunctionChain;
                  
                  а если сделать по другому, но могут начаться проблемы с компиляторами
                    PFunctionChain = ^TFunctionChain;
                    TFunctionChain = function(const value: String): PFunctionChain;
                  
                  Это скомпилируется
                  Но если вы попытаетесь определить такую функцию:
                  function functionChain(const value: String): PFunctionChain;
                    begin
                      writeLn(value);
                      result:= @functionChain;
                    end;
                  
                  то в lazarus это скорее всего вообще не соберется
                  а в delphi если и соберется то может свалится при выполнении
                  да и код использования будет какой-то не такой:
                  functionChain('1')^('2')^('3');
                  
                  чтобы сделать код использования таким:
                  functionChain('1')('2')('3');
                  
                  можно попытаться объявить функцию как возвращающую TFunctionChain а не PFunctionChain
                  function functionChain(const value: String): TFunctionChain;
                  
                  но тогда может не скомпилироваться код
                  functionChain('1')('2')('3')
                  
                  или
                  functionChain('1')^('2')^('3');
                  
                  но при этом возможно сможет скомпилироваться код:
                  functionChain('1')^('2')('3');
                  
                  На некоторых версиях это может работать, даже на совсем древних.
                  • 0
                    Конечно. Но сам случай — не самый распространенный, мягко говоря.
                  • 0
                    а в delphi если и соберется то может свалится при выполнении

                    Для интереса прогнал — нет, не упадет.

                    functionChain('1')('2')('3') — очень вырвиглазный код. Я понимаю, что пример синтетический, но если бы увидел в реальной жизни что-то подобное, с последовательным вызовом через указатели, то сказал бы, что код дурно пахнет.
                    • 0
                      конечно
                      это синтетический пример для демонстрации проблем однопроходного компилятора
                    • 0
                      Но вообще-то ничего особо страшного тут нет — в C++ никто не удивится функтору, возвращающему функтор
                      • 0
                        Страшного нет, просто проблема надуманная. В конце концов, можно typecast ами обойтись. Но (1)(2)(3) — «веселый» код, особенно в отладке.

                        Кстати, интересно, как эта проблема решена для классов:
                        type
                          TAbc = class;
                        ...
                        ...
                          TDef = class
                          public
                            function Xyz(): TAbc;
                          end;
                        ..
                        ..
                          TAbc = class
                          ...
                          ...
                         end;
                        
                        • 0
                          Да, из-за однопроходности компилятора необходима специальная синтаксическая возможность для обхода ограничений однопроходности. Это forward реализации функций, допустимость обработки указателей на тип до определения самого типа, отделение интерфейсов от реализации и вот такое специальное опережающее описание класса. Ну и стоит ли овчинка однопроходности выделки такой ценой?
                          • 0
                            допустимость обработки указателей на тип до определения самого типа

                            Это нормально. Указатель приводится к чему угодно.

                            отделение интерфейсов от реализации

                            Это тоже замечательно — мне нравится такое разделение. Напротив, мешанина — нечитабельна.

                            Ну и стоит ли овчинка однопроходности выделки такой ценой?

                            Конечно. 99% случаев покрывается, а 1%м вроде синтетического примера выше можно поступиться.
                            • 0
                              допустимость обработки указателей на тип до определения самого типа
                              Это нормально. Указатель приводится к чему угодно.
                              Это ужасающе в плане придумывания костылей.
                              Почему forward-определения указателя недостаточно для класса?
                              Потому что класс и так передаётся только как ссылка.
                              Поэтому мы сделаем новый тип forward определений для класса.
                              И для интерфейсов тоже.
                              Но функция тоже ссылочный тип. А что с функциями?
                              Да и фиг с ними — добавлять еще одни костыли глупо, а сделать по-нормальному — сложно.
                              отделение интерфейсов от реализации
                              Это тоже замечательно — мне нравится такое разделение. Напротив, мешанина — нечитабельна.
                              Да уже не осталось языков которые требуют такого отделения. Это всё анахронизмы, как и секция var.
                              Конечно. 99% случаев покрывается, а 1%м вроде синтетического примера выше можно поступиться.
                              Если какая-то простая конструкция из-за какой-то несусветной причины не может быть описана на языке — то это очень говорит о продуманности такого языка, тем более языка, претендующего на академичность.
                              • 0
                                Это ужасающе в плане придумывания костылей.

                                То же, что и с Си — мол, много способов «выстрелить в ногу». Хочешь — стреляешь, не хочешь — делаешь нормально.

                                Почему forward-определения указателя недостаточно для класса?
                                Потому что класс и так передаётся только как ссылка.

                                Этот обрубок — это и есть forward, просто по-другому описан, в отличие от процедур.

                                Но функция тоже ссылочный тип. А что с функциями?

                                Ну вот и ответ, в принципе: с классами это было людям нужно — добавили способ forward описания. С функциями — не было нужно.

                                Да уже не осталось языков которые требуют такого отделения. Это всё анахронизмы, как и секция var.

                                И? Мне лично так нравится больше: читаемость лучше. С секцией var проблем не вижу: мне нравится, когда код структурирован. Тут — объявления, тут — код. Учитывая, что хорошим тоном является разбиение процедур, секция var так и так в поле видимости, плюс/минус. Если функция — простыня на 3 экрана, тогда, да, объявлять по месту лучше. Но это уже не особо хорошее оформление кода.

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

                                Да это не простая конструкция, это надуманная проблема, а не реальный код. Не представляю, чтобы кто-то вызывал цепочку таким образом — попробуй отладь потом такой код.
                                • 0
                                  А, да, насчет академичности: в оригинальном Паскале не было ссылок и процедурных типов.
                                  • 0
                                    Вроде как в виртовском паскале есть параметры типа процедура, но нет переменных типа процедура (короткая дискуссия на эту тему).
                                • 0
                                  То же, что и с Си — мол, много способов «выстрелить в ногу». Хочешь — стреляешь, не хочешь — делаешь нормально.
                                  Я имел в виду синтаксические костыли.
                                  Ну вот и ответ, в принципе: с классами это было людям нужно — добавили способ forward описания. С функциями — не было нужно.
                                  Это называется — отсутствие общего подхода. Если бы язык был как-то стандартизирован, такой фигни бы не было. А так — язык одного актёра разработчика.
                                  С секцией var проблем не вижу: мне нравится, когда код структурирован. Тут — объявления, тут — код.
                                  Вам ничто не мешает писать так и в C++ и игнорировать удобство RAII. Но это же не значит что надо превозносить такое искусственное ограничение языка.
                                  попробуй отладь потом такой код
                                  ограничения отладчика конечно важны, но тоже не являются непреодолимым барьером.
                                  Например я лет 10 назад перешёл с idea на eclipse потому что у тогдашней idea были проблемы с отладкой анонимных классов. В случае же delphi не получится сменить ide или компилятор, поскольку, увы, альтернатив нет.
                                  • 0
                                    Это называется — отсутствие общего подхода. Если бы язык был как-то стандартизирован, такой фигни бы не было. А так — язык одного актёра разработчика.

                                    Почему же? В случае класса нам нужна подсказка компилятору о типе данных, а в случае функции — нет. Это разные области: в одном случае — тип данных, в другом — объявление процедуры. Поэтому и синтаксический подход различен. Это только человеку кажется «мы же и там и там на что-то далее по тексту ссылаемся». Вот если бы подсказка для процедурного типа была бы реализована иначе, чем для типа «класс», тогда вы были бы правы. Но такой подсказки нет вовсе, поэтому про неоднородность говорить не приходится.

                                    Вам ничто не мешает писать так и в C++ и игнорировать удобство RAII. Но это же не значит что надо превозносить такое искусственное ограничение языка.

                                    Не мешает. Я просто говорю, что это не проблема. Вообще. Искусственное ограничение? Тогда любое синтаксическое правило — искусственное ограничение. Можно точно так же сказать, например, что перечисление включаемых модулей (или include'ы заголовков в C/C++) — тоже искусственное ограничение. Можно сказать, что, например, необходимость применения break'а в switch'е — искусственное ограничение, вызванное реализацией таблицы переходов. Или необходимость в цикле с условием всегда использовать while.

                                    ограничения отладчика конечно важны, но тоже не являются непреодолимым барьером.

                                    Не в ограничении отладчика дело, просто сама конструкция нечитаема. Мне, например, не нравится фактически самомодифицирующийся код.

                                    В случае же delphi не получится сменить ide или компилятор, поскольку, увы, альтернатив нет.

                                    Во-первых, тот же lazarus.
                                    Во-вторых… а и не надо. За 6 лет, что я пишу на delphi по работе, единственное ограничение, которое изредка досаждает — отсутствие полноценных шаблонов. И то, частично это реализовано.
                                    Никто не спорит — те же плюсы намного мощнее, универсальнее и пр. Я лишь говорю, что готов поступиться 1% функционала за ту же быструю компиляцию и гарантированную структурированность (=лучшую читаемость) программы.
                                    • 0
                                      Поэтому и синтаксический подход различен.
                                      Это костыли а не подход.
                                      В одних случаях указатель автоматически разъименовывается, в других нет, в третьих возникает конфликт и для получения указателя надо использовать @@ вместо @ и все это зависит от параметров компиляции и версии компилятора.

                                      break'а в switch'е — искусственное ограничение, вызванное реализацией таблицы переходов
                                      если бы в switch не было возможности перехода из одного case в следующий, то чтобы съемулировать такую возможность пришлось бы использовать goto или разделение на функции

                                      За 6 лет, что я пишу на delphi по работе, единственное ограничение, которое изредка досаждает — отсутствие полноценных шаблонов. И то, частично это реализовано.
                                      Шаблоны в pascal ещё 25 лет назад эмулировались с помощью include.

                                      А вот что меня сейчас досаждает — то что generic-и в java никогда не будут иметь возможностей шаблонов C++, поэтому приходится заменять статическую типизацию на динамическую выдумывая как бы при этом сохранить типобезопасность.

                                      гарантированную структурированность (=лучшую читаемость)
                                      Ничто не мешает писать структурировано и читабельно на языке в котором много плюшек.
                                      Не хотите — ну не пользуйтесь всеми плюшками. Но не говорите за всех.
                                      • 0
                                        Это костыли а не подход.

                                        Это разный подход, а не костыль. Разные конструкции — разные подходы. Объявление процедуры — одно, тип данных — совсем другое. Вас же не удивляет, что класс объявляется при помощи class {, а процедура — при помощи void abc () {?

                                        если бы в switch не было возможности перехода из одного case в следующий, то чтобы съемулировать такую возможность пришлось бы использовать goto или разделение на функции

                                        Это лишь один пример «искусственного ограничения».

                                        Шаблоны в pascal ещё 25 лет назад эмулировались с помощью include.

                                        Эмулировать через задницу можно что угодно, я про встроенную поддержку.

                                        Ничто не мешает писать структурировано и читабельно на языке в котором много плюшек.

                                        Не мешает. Я просто говорю, что блоки var — не стоящая внимания «проблема».

                                        Не хотите — ну не пользуйтесь всеми плюшками. Но не говорите за всех.

                                        Так я не говорю за всех, чего это вы взъелись? Это вы начали беседу про «оно того стоит?». Я лишь ответил, что в этом языке, по моему мнению, выбран разумный баланс — пожертовали редко используемыми мелочами. Код структурирован и легче читается — значит, его легче поддерживать.

              • 0
                К сожалению, я слишком плохо знаю C++ чтобы ответить на этот вопрос.

                Вот что пишут в Интернете:

                One reason why Delphi may be faster to compile than C++ is that Delphi
                has a proper module system, whereas C++ still uses the old #include
                preprocessor hack. The old #include hack has the drawbacks that the
                meaning of each header file included may depend on what macros are in
                scope at that point. So the effect of including header files in a
                different order might be different. This makes precompilation of
                header files much more difficult, complicated, and ineffective than
                for Turbo Pascal units. As a result, C++ compilers tend to parse the
                headers each time they are read, rather than precompiling them.

                Мой кривой перевод:
                Одна из причин, почему компилятор Delphi может быть быстрее компилятора С в том, что Delphi имеет продуманную систему модулей, в то время как C использует «старинный» хак с директивой Include. Использование include приводит к тому, что значение каждого заголовочного файла может трактоваться по-разному в зависимости от того, какие макросы находятся сейчас находятся в области видимости. Это делает прекомпиляцию .h файлов гораздо более сложной и трудозатратной задачей по сравнению с компиляцией модулей в Паскале/Delphi. В результате C++ компиляторы как правило выполняют парсинг заголовочных файлов каждый раз когда эти файлы прочитываются, вместо того чтобы прекомпилировать их заранее.
                • 0
                  Конкретно эту проблему можно обойти активно используя прекомпилированные хидеры. Помнится, у нас на проекте таким способом удалось ускорить полный ребилд в 10 раз с 20 минут до 2-х.
                  Но это костыль, который у каждого компилятора сделан по своему, и к тому же нарушает читабельность.
        • 0
          Разделение на библиотеки, precompiled headers, меньше буста в на каждый чих, многопоточная компиляция…
          … да и хабр можно почитать пока компиляемся!
  • 0
    иногда приходится переписывать медленные части веб-приложений на с++
    и по правде говоря, из-за указанных минусов (отсутствие менеджера пакетов, модулей, сложная сборка и тд) пробую переходить на Rust
    Пока нравится, но к сожалению, пока слабая инфраструктура и неуверен «выстрелит» ли язык или «затухнет»
  • +3
    Я бы очень хотел спросить Эрика: что он знает и думает о Qt? Boost немного как будто бы антогонист, но их прекрасно можно и нужно сочетать. Как он считает, Qt хорошо подходит по духу C++? На мой личный взгляд Qt невероятно мощная вещь, которая внасет весомый вклад в будущее C++ и мне обидно, что в интервью о библиотеке ни слова.
    • 0
      Есть такой холивар, что Qt — это просто gui модули и больше нигде использовать его нельзя, т.к. медленно, много, непонятно и прочее. Настоящие С++ программисты ядра приложений пишут используя только boost, а Qt ни в коем случае нельзя.
      Про IDE Qt Creator тоже ни слова. Я вот два года в нем проработал и сейчас просто в шоке от Visual Studio 2012. Она даже с платными плагинами не догоняет Creator по возможностям рефакторинга и поддержки автодополнения, да и лагает блин периодически. Ну и естественно у креатора есть Qt специфические фичи, которых в студии вообще никогда не будет.

      С другой стороны автор специализируется на С++ библиотеках без лишних зависимостей, зачем ему Qt.
      • 0
        По поводу Qt Creator — пытался работать с ним, но никак не ужился с отсутствием нормального дебаггера. Именно из-за шикарного дебаггера — использую только студию (рефакторинг — с плагинами, автодополнение — в 13й — очень даже не плохо). Ну а вне Windows — Qt Creator единственная IDE
        • 0
          Не понимаю в чем проблема, дебаггер в Qt Creator можно выставить такой же виндовый как в студии.

          Тест на работу автодополнения — что найдется если в студии, если попробывать найти все ссылки на переменную? У меня почти всегда находит все вхождения литерала по решению, что делает невозможным даже тупо переименование переменной. Можно ли на лету менять сигнатуру методов и функций (чтобы автоматом менялось и объявление)? Можно ли вставлять объявления от выбранных виртуальных методов в наследуемом классе?

          • 0
            «такой же виндовый как в студии.».
            Вы чуть-чуть неправы. Сам пользуюсь QtC. В нем можно выбрать 3 дебаггера: CDB (Microsoft Console Debugger,) GDB, LLDB. В Visual Studio не используется CDB! там отладчик встроен в саму среду и использует dll-ки компилятора. У него общая модель кода с компилятором=)

            А про автодополнение в студии — обычно люди без VisualAssist ее не используют, стандартный функционал уж очень урезанный =) Я кучу дополнений ставил на 2010, чтобы приблизить ее к удобству QtC.
            «Можно ли на лету менять сигнатуру методов и функций » — в VA да. там так и работает.
            а про выбранные виртуальные методы — раньше не было ;) сейчас не знаю. Очень клевая вещь, но не самая частая, я не каждый день ее юзаю.

            К слову, попробуйте объявить vector a;
            a[1].Method();
            И затем переименовать метод в QtC и студии. в QtC сработает только с Clang code model. в студии — на отлично =)
            Но тем не менее, Creator — наше все и я его люблю куда больше и предан ему!

            Просто небольшое замечание по объективности.
            • 0
              Так естественно я поставил VisualAssist и несколько других дополнений, перенос строки например, который тоже работает хуже, чем в Qt Creator — там строка подстраивается под выравнивание блока, в VS нет.

              Как в VA менять на лету? Я знаю только, что можно поменять сигнатуру через вызов специального диалогового окна, а если ты по ходу поменял сигнатуру функции, без вызова специального метода, то менять её придется в ручную в объявлении. В Qt Creator есть хот кей для этого, он сам по уже изменной сигнатуре подправит объявление, и кстати корректно переименует параметры метода или функции везде, где они использовались.

              Не совсем понял что предлагаете сделать с вектором. Отнаследоваться от вектора, объявить метод и потом его переименовать?
              • 0
                хабрапарсер угловые скобки поел) нет, не наследоваться вектор с типом SomeClass я написал. Модель кода в QtC не понимает тип элементов вектора, и дополнение и рефакторинг не работают. Даже в 3.5.
                • 0
                  Поэкспериментировал. Оказывается, с std::vector действительно не понимает, а вот с QVector (и прочими qt-шными контейнерами) понимает прекрасно. В целом действительно модель кода слабовата, но работает она быстро и для многих вещей ее хватает.
              • 0
                Время попробовать Resharper C++. Он очень ок.
          • 0
            Тест на работу автодополнения

            Все действия в дальнейшем с использованием VA
            найти все ссылки на переменную

            Выделяем переменную shift + alt + f и VA находит все места где используется эта переменная.
            переименование переменной

            shift + alt + q выбрать пункт rename
            менять сигнатуру методов и функций

            shift + alt + q выбрать пункт change signature
            Можно ли вставлять объявления от выбранных виртуальных методов в наследуемом классе?

            shift + alt + q выбрать пункт Implement Virtual Methods

            Ещё что-то нужно?

            Вынос метода — есть, вставка инклудов — есть, создание переменных — есть, имплементация методов\ функций — есть, Переименование файлов — есть, снипеты, скобки по выделенному — есть, поиск и переход — есть, показать объявление внутри маленького окна — есть (alt + F12 это даже фича студии а не VA)
            • 0
              shift + alt + f

              Проверил только что, взял первый попавшийся ашник и захотел найти все ссылки на параметр в методе. Нашел только ссылку в самом ашнике, т.е. ничего. Но в теле функии таки нашел, и не по всему солюшену, а именно где ссылка на объект. На много лучше, чем find all reference.
              shift + alt + q

              Не знаю как это будет работать, если все ссылки не находит или находит вхождение строки. Как то переименовал метод через какой то rename, возможно не через этот, так поменялись все одноименные методы по всему солюшену. Откатил обратно и с тех пор даже не пытаюсь использовать.
              shift + alt + q

              Это я знаю. Я говорил про вариант на лету. Я поменял, а Qt Creator по хоткею все переименовал, без вызова доп окошек. К тому же, если меняешь имена переменной в сигнатуре, в теле метода имена переменной не меняются. И опять таки, ищутся ВСЕ однотипные сигнатуры по всему солюшену и нужно вручную галками отключать не нужные.

              имплементация методов\ функций — есть

              Это вот пожалуй единственное чем можно пользоваться в студии.
              • 0
                Проверил только что, взял первый попавшийся ашник и захотел найти все ссылки на параметр в методе. Нашел только ссылку в самом ашнике, т.е. ничего.

                Странно, у меня находит везде, ещё ни разу проблем не было, даже на больших проектах в несколько М строк, какой версией пользуетесь? И на всякий случай, вы ашник открыли в рамках проекта, или просто как отдельный файл?
                • 0
                  version 10.9.2068.0 built 2015.06.09

                  Открыл в рамках проекта естественно.
                  • 0
                    У меня даже более старая версия, и всё работает. Значит вам не повезло, или va не успел проанализировать проект.
                    • 0
                      Не знаю, что то мне вообще не в кайф искать все эти плагины и разбираться как они работают.

                      Анализировать студия тоже очень любит. По F2 иногда тупит на пару минут, что то там индексирует.
                      Кстати, а вот извлечь функцию тоже в VA есть? То, что я видел в студии извлекает метод, при этом не пытается даже завести возвращаемые из функции параметры — всегда void результатом ставит, а параметры функции только входные. Это норм для студии и VA?
                      • 0
                        Кстати, а вот извлечь функцию тоже в VA есть?

                        Есть
                        при этом не пытается даже завести возвращаемые из функции параметры

                        Всё зависит от того что в коде который выделяешь.
                        • 0
                          Это понятно, что зависит. Просто иного я еще не видел.
        • –2
          Дебагеры у VS и QtCreator свои собственные и различаются? Вот это новости.
          • 0
            Ну зачем столько сарказма? Когда используешь cdb (другие не пробовал) из-под QtCreator-а, лично у меня — он подвисает очень часто и, по сравнению со встроенным Visual Studio Debugger-ом — всё продвигается медленнее. Просмотр переменных в QtCreator-е просто ад и ужас, особенно, если это обычные строки. Watch-окна, вроде как, нет (с удобными штуками такими как @ err,hr). Окна потоков/подключённых процессов так же как и окна пам'яти/call stack-а — удобнее в студии. Такой штуки как Autos в QtCreator-е, если я не ошибаюсь, вообще нет (так же как и дизасемблера ?). Коннектиться к удалённому процесу — намного проще, если ещё и к vmware-виртуалке (удобный плагин, всё в один клик). Как подключить KD — я так и не нашёл (хотя, признаюсь, гуглил не больше 2х минут).

            • 0
              Дизасм? дизасм кода в отладчике в QtC есть. про KD — не понял =)
          • +1
            Да, дебаггер студии не использует CDB, а использует либы и модель кода от компилятора. Он встроен в ИДЕ. см. коммент мой выше по ветке.
      • 0
        Это мнение, по-моему, круто устарело (или у вас был сарказм? я не очень понял). Современный Qt 5, если его использовать в связке с алгоритмами из stl не сильно медленнее чистого С++, при этом совершенно всеобъемлющий, потакающий проектировать правильно, и высокоуровневый (а значит быстрее писать и меньше ошибок совершать) аки Java, если писать еще и на новых стандартах С++. Хотя часто мне код уже Python напоминает, даже не Java.
        Прогаю на Qt в QtCreator около 4 лет. Студии тоже знаю все версии. Boost, если уж на то пошло, тоже использовал и использую. Мнения о студиях такого же — для гиганской корпорации просто ужасная IDE, проигрывающая настроенному правильно QtCreator по полной.
        • +1
          Я такого же мнения о Qt, но холивар то есть.
          • 0
            Я бы в холивар подкинул тот факт, что Qt не потащишь в средний embedded, где лимиты памяти 4-8 Мб. а вот stl и boost — да =)
            QtCore+Network урезанные флагами у меня добавляют под арм сборку больше 2Мб, а boost — всего 300 Кб. Ну, понятное дело, что подмножество используемых фич очень важно. Но даже просто QString заюзать — очень много за собой тянет.

            Вот для десктопов — я согласен, и для консольных, и для сетевых приложений лучше не придумать. Контейнеры ничуть не хуже stl.
            • 0
              Работал на плате с 8 мб памяти. Из них образ системы вместе с Qt занимал 4 мб. Возможно вы не использовали флаг оптимизации для уменьшения размера бинарников.
              • 0
                У меня только linux busybox 3mb отъедает. Так что это вряд ли получится.
      • +1
        Даже с clang code model автодополнение и контекстные подсказки Qt Creator сливают, к сожалению, студии, когда дело доходит до более-менее сложных шаблонов
    • +3
      Вот что на ваш вопрос ответил Эрик:
      Я признаюсь, что у меня нет опыта использования Qt. Если бы я занимался разработкой приложений, мне бы наверняка пригодилась её функциональность, но ничего не могу сказать про неё с точки зрения проектирования.

      Оригинал
      I confess that I have no experience using Qt. If I were an application developer, I'm sure I would find the functionality in Qt useful, but I can't comment on its design.
      • 0
        Благодарю! :)
  • +7
    Кстати, в эту пятницу Эрик выступает с keynotes на конференции C++ Siberia в Новосибирске.
  • 0
    Но, если бы мне нужно было выбрать всего одну штуку, которая больше всего повлияла бы на C++, я бы выбрал простой, надёжный и мощный менеджер пакетов.


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

    За три года несколько раз всё переписывал. Сейчас пришёл к выводу что для правильной генерации интерфейсов тонких модулей, основанных на библиотеках, нужна кодогенерация. Неделю назад как раз закончил работу над генератором парсеров, на основе которого буду разбирать плюсовый код.

    Если кто-нибудь хочет принять любое участие в работе над менеджером пакетов — был бы очень рад. Обсуждение: советы, пожелания, угрозы — тоже приветствуются.

    Мне кажется, для её решения, возможно нужен гигант вроде Майкрософта, Гугла (или Яндекса?). Это сложная, большая, занудная и не приносящая славы задача того типа, которыми не любят заниматься волонтёры.


    А есть какие-нибудь периодические открытые тусовки в Яндексе, куда можно прийти и поговорить о судьбах С++? Я в своё время через знакомого пытался выйти на людей из Яндекса, но дело забуксовало.
    • +1
      Если кто-нибудь хочет принять любое участие в работе над менеджером пакетов — был бы очень рад. Обсуждение: советы, пожелания, угрозы — тоже приветствуются.

      Если я правильно понял Эрика он сожалел о судьбе bii code. Который вроде бы почти смог, но ресурсов не хватило. Они открыли код и вроде бы их собирались интегрировать в CLIon.

      А есть какие-нибудь периодические открытые тусовки в Яндексе, куда можно прийти и поговорить о судьбах С++? Я в своё время через знакомого пытался выйти на людей из Яндекса, но дело забуксовало.


      Так на встречах C++ User Group периодически выступают ребята из Яндекса. Плюс, у Яндекса есть C++ Party
      • 0
        он сожалел о судьбе bii code

        Кстати, а что случилось с bii code? На сайте у них вроде ничего такого не написано…
        • 0
          Вот здесь они все пишут. У них именно бизнес не получилось завести. То есть, они рассчитывали получать с этого хоть какой-то профит. Однако, не смогли набрать достаточное количество корпоративных пользователей.
      • +1
        Спасибо за наводку на bii code. Очень ценно было почитать о том, как ребята это сделали.

        вроде бы их собирались интегрировать в CLIon


        На их сайте написано что Biicode uses CMake to configure and build your projects and it is compatible with many IDEs and version control systems. Тобишь, вроде, со всеми может использоваться через консоль. В CLion bii code, видать, будет встроен в интерфейс IDE.

        Так на встречах C++ User Group периодически выступают ребята из Яндекса


        Спасибо, схожу как-нибудь.
    • +1
      Простите, а зачем вам свой парсер C++? Если вы думаете что можно получить AST только на основании парсинга токенов, то вы ошибаетесь. Это один из самых извращенных языков в этом смысле.

      С другой стороны, если задача стоит только в парсинге каких то обособленных конструкций и не ставится задача семантического анализа исходников, то это вполне возможно.

      Я советую посмотреть в сторону clang/LLVM, которые можно использовать как бакенд для своих задач. При этом компилятор предоставляет все средства для анализа, но без лютого геморроя.
      • 0
        Парсер нужен для генерации pimpl-обёрток для классов библиотек. Дело в том, что, в отличие от bii code, в моей системе решения зависимостей, зависимости подтягиваются в виде скомпилированных библиотек (статических или динамических) + хедеров, а не исходников с реализациями классов. Для универсальности хедеров (и, соответственно, возможности простого переключения между статической и динамической библиотекой) хотелось использовать идиому pimpl.

        Насчёт clang — интересно. Нашёл о нём статью на хабре, там как раз тема использования в качестве кодогенератора обсуждалась. Если забуксую со своим парсером — гляну.
        • 0
          Вы совершенно точно зароетесь насмерть с парсингом. В C++ построить фактическое AST возможно только с учетом семантики языка и только GLR парсером.

          В основном проблема в шаблонах. Шаблоны являются тьюринг полными. Соответственно, при инстанциировании шаблонов вам неминуемо придется возиться с семантикой.

          Помимо этого существует просто кретинистически много разных синтаксических конструкций и правил парсинга, которые мы в 99% времени не встречаем. Ну например, ключевое слово template может встречаться и внутри выражений. Не говоря уже про накие няшности как foo->Bar::baz(), foo->~Foo() и (object->*method)()

          Даже просто воскурить стандарт и написать по нему правила разбора это работа минимум на год. Но… зачем? Если есть готовый компилятор, который предоставляет все эти возможности и гарантированно будет поддерживаться и содержать минимум ошибок.
          • 0
            Да. Почитал про clang — скорее всего, всё же его использую. А парсинг плюсов на своём парсере тогда чуть отложу — сделаю когда время будет.

            Даже просто воскурить стандарт и написать по нему правила разбора это работа минимум на год.


            Кстати, начинал эту работу. Осилил до этого момента где-то одну десятую часть: идентификаторы, все литералы, декларации классов и где-то половину вещей, связанных с шаблонами. У меня парсер хавает не БНФ, а представление разбора в виде графа (мне такое представление кажется более наглядным) — поэтому осмыслял путём перевода БНФ из стандарта в представление в виде графа.
            • 0
              Осмыслял путём перевода БНФ из стандарта в представление в виде графа.

              Это похоже на подход применяемый в ANTLR парсере. LL(*) если я правильно помню. В отличие от GLR/LR, это разбор «сверху вниз», а не «снизу вверх».
              • 0
                Ух ты, какую я мудрёную штуку сделал, оказывается. Не понял половины слов, пошёл гуглить.
            • 0
              Еще пару слов о парсерах. Проект KDevelop на данный момент использует кастомный парсер C++ для целей code assist, refactoring и syntax highlight. Так вот разработчики говорят что их парсер это «50 тысяч строк глючного, сложно поддерживаемого и трудно расширяемого кода», который им приходится тащить на себе и развивать от версии к версии. А ведь им приходится еще и тащить парсинг препроцессора на на уровне синтаксиса, что тоже добавляет геморроя. С большой вероятностью, вам пришлось бы повторить этот ад у себя.

              К счастью, уже существует проект и форк по пересаживанию KDevelop на парсер clang. И я сам его жду с нетерпением, потому что работа с шаблонами будет еще проще и полнее чем сейчас.
              • 0
                А за счёт чего clang умудрился избежать всех этих проблем? Его позже разрабатывали?
                • 0
                  Да, clang писался позже, с учетом опыта и ошибок предшественников (GCC), так что архитектура и качество кода у него лучше. И он сразу был ориентирован на наличие API для встраивания в другие проекты, а не только использование в качестве отдельного компилятора. Но он всё равно сложный, потому что сам язык C++ сложный, и от этого никуда не деться. Просто поддерживать (и разрабатывать, ведь C++ на месте не стоит) один парсер гораздо проще, чем каждый проект (IDE) будет пытаться делать это самостоятельно. Ну и использование libclang гарантирует, что ваша программа будет понимать код точно также, как это делает настоящий компилятор, что хорошо.
            • 0
              Посмотрите ещё на проект CastXML. github.com/CastXML/CastXML
              Это форк GCCXML. Строит AST в XML формате. Использует Clang.
              • 0
                Спасибо за наводку на библиотеку. Хотя в моём случаи формирование полного AST в виде XML это лишние. У меня задача простая: считать информацию о классах и сформировать для них классы-обёртки, реализующие идиому pimpl. Сделать это желательно за минимальное время. В идеале — с использованием подхода вроде SAX для XML (Clang, вроде, позволяет что-то такое делать судя по беглому осмотру).

                П.С.: Хотя сохранение AST в XML может быть способом сохранения информации для инкрементального билда. В этом смысле CastXML действительно может быть полезен.
        • 0
          для генерации pimpl-обёрток для классов библиотек

          Ваш менеджер пакетов будет подменять хедеры?
          Boost или другие header-only библиотеки им можно будет подключить? Если нет — зачем он нужен?
          • 0
            Можно будет. Кодогенератор будет копировать шаблонозависимый контекст напрямую. Обёртки же будут формироваться для свободного от шаблонов контекста.
      • 0
        Про свой парсер, кстати, статью планирую на хабру написать. Не подскажете какую лицензию можно поставить на исходники при публикации чернового демонстрационного кода библиотеки — чтобы запретить пока использование сорцов в любых публикуемых проектах? (Вопрос по библиотеке на Тостере).
        • +1
          Нельзя просто взять и запретить то, что однажды было выложено в сеть.

          Зачем? Если вы хотите поделиться проектом с сообществом, то выкладывайте под открытыми лицензиями и не мучайтесь. Не стоит переоценивать желание людей кидаться на полуготовые исходники и красть их. Даже вполне себе оформленные проекты валяются на гитхабе годами и никакой активности не наблюдается.
          • 0
            Не стоит переоценивать желание людей кидаться на полуготовые исходники и красть их


            Ага. Ну, ок. В принципе, можно. А конверсию затраченного на библиотеку времени можно будет как-нибудь погодя получить — хотя бы через те же пожертвования на проект если дело выгорит.
    • 0
      Если кто-нибудь хочет принять любое участие в работе над менеджером пакетов — был бы очень рад. Обсуждение: советы, пожелания, угрозы — тоже приветствуются.

      Тут проблема вот в чем: чтобы сделать это действительно удобным нужно поставлять бинарники. И вот тут проблема, т.к. нужно одно из двух:
      • Или компилировать библиотечку всеми компиляторами × версиями компилятора × битность × другие настройки, что весьма накладно; или
      • Компилировать библиотеки на стороне клиента, что требует наличие подходящих билд-систем а также уйму свободного времени, т.к. компилировать какой-нть Boost (даже на RAM-диске и 32 процах) — процесс небыстрый, а вся суть пакетных менеджеров — чтобы быстро работало.

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

      Насчет biicode — у них просто бизнес-модель не выстрелила, насколько я понимаю. Nuget для С++ кстати тоже не подарок.
      • 0
        Или компилировать библиотечку всеми компиляторами × версиями компилятора × битность × другие настройки, что весьма накладно


        Я вижу решением что-то вроде гибридной компиляции. Мы лениво выполняем сборку библиотеки в основном на стороне сервера репозитория в момент запроса библиотеки (например, на виртуальных машинах), но, если у клиента специфическая архитектура, которой нету в поддерживаемых сервером — результат компилируется на машине клиента и по его желанию может быть отправлен на репо чтобы другие им пользовались. В этом случаи нужно чтобы хотя бы кто-нибудь хотя бы раз собрал библиотеку под соответствующую архитектуру.

        Поэтому верится что для этого существует некая некоммерческая ниша.


        Почему обязательно некоммерческая? Можно создать магазин библиотек с гибкой настройкой лицензий: от полностью freeware с возможность изменения кода до платной для личного пользования. Вот тут ребята так пробуют зарабатывать (нашёл в процессе поиска на вопрос).
        • +1
          Так а собственно вопрос о настройках остается открытым. Например я библиотеки компилирую с поддержкой AVX, очевидно что для общего пользования так делать нельзя. Значит мы должны шипить везде неоптимизированные либы. А это печально. Еще есть битность, линковка к стандартной библиотеке (статическая или динамическая, многопоточная или нет), и куча всего.

          Если делать это on demand, нужно фактически иметь виртуалки на все возможные компиляторы и операционные системы. Компиляторы и вообще системы эволюционируют, поэтому нужно держать целый зоопарк разных версий и настроек. Я не говорю про то что по перформансу это нехило так выходит, т.к. в С++ компиляция это болезненная операция. По памяти кстати тоже, т.к. буст например генерит гигов 10 всякого шлака.

          Тем не менее идея как мне кажется неплохая, т.е. заниматься этим определенно нужно. Только нужно делать это настолько удобно чтобы подход «а не, я все сам соберу» был неэкономичен.

          • 0
            Если делать это on demand, нужно фактически иметь виртуалки на все возможные компиляторы и операционные системы


            Ну да, проблема комбинационного взрыва есть. Поэтому я и предложил в качестве решения «в лоб» делать что-то вроде распределённой билд-системы, когда пользователь репозиторием может собрать библиотеку у себя, а потом расшарить сборку со своими настройками для всех пользователей репозтория.

            П.С.: Кстати, такую систему распределённой сборки можно сделать даже более абстрактной, не только для сборки плюсов, но и для сборки чего угодно. Выйдет что-то вроде глобальной торрент-make системы.
            • 0
              Так это называется «поставить TeamCity у себя в конторе», не? Или вообще в сетевую шару залить. А хочется всем сделать хорошо.

              А распределенные системы сборки уже существуют, только что-то почти никто их не использует, что печально.
              • 0
                Система будет состоять из двух частей:

                1. Решатель зависимостей. Смотрит на то, какие модули должны поставляться с нашим модулем. Выполняет запрос ресурсов из репозитория модулей по заданным настройкам (полная информация о сборке: ось, компилятор, какие-то таги с пожеланиями от пользователя, и.т.д). В идеале должен изменять файл проекта для IDE, выставляя нужные флаги компиляции для линковки статических библиотек, и.т.д.
                2. Репозиторий модулей. Возвращает скомпилированный в нужном виде модуль (на основе переданных настроек) — в виде статической или динамической библиотеки. Если модуля, собранного с нужными настройками нету — репозиторий пытается собрать у себя, а, если и это не возможно, загружает исходники к пользователю, собирает их на машине пользователя, после чего отсылает обратно на репозиторий чтобы все люди получать собранный модуль.

                При этом, если проводить аналогию с миром Java, где есть ещё Spring для внедрения зависимостей, в С++ механизм внедрения зависимостей может использовать, условно говоря, статический полиморфизме, когда реализации функционала подходит по именам и вызовам из других модулей (аналог интерфейса), но при этом имеет другой корневой include.
                • 0
                  отсылает обратно на репозиторий чтобы все люди получать собранный модуль

                  мне единственное интересно, как контролировать что то, что юзер залил, валидно? например, boost.mpi можно собрать относительно всяких разных MPI библиотек. или можно собрать с оптимизациями по AVX. и все, цикломатический взрыв или как его там…
                  я считаю что нужно чуть по-другому: общий репо можно делать только для сорцов, чтобы можно было скачать их локально – их, и конечно механизмы их компиляции. тут тоже адов ад: например, скачиваешь репо, а оно использует visual studio и только, и компилит под 32 бит, и в путях жестко прописаны папки, которых локально нет или в других местах лежат. вообщем, вопросов очень много. и в основном из-за того, что нет никакой бинарной совместимости.
                  я бы лично конечно перевел каждое репо на cmake. только это не всегда работает (см. например буст)
                  • 0
                    например, boost.mpi можно собрать относительно всяких разных MPI библиотек. или можно собрать с оптимизациями по AVX. и все, цикломатический взрыв или как его там…


                    В процессе работы я выяснил, что, например, g++ из minWG умеет собирать библиотеки с предекларированными классами и функциями, реализация которых может линковаться в процессе сборки приложения. Надеюсь, другие компиляторы такое тоже умеют. Если да — то проблема со сборкой одних библиотек относительно других и использование такой сборкой третьими библиотеками отпадает.

                    Да и потом — библиотеки не занимают так уж много места. Можно сделать очень грубую прикидку. Пусть пять мегабайт будет одна сборка (а они, надеюсь, будут меньше, я верю в микромодульную архитектуру приложений). Пусть для неё будет пять разных конфигураций, каждая будет иметь пять значений (там, оптимизации разные, и.т.д). Выходит 5*5*5=125 мегабайт на одну библиотеку. Итого — на один гигабайт влезет восемь библиотек. На террабайтный диск — восемьсот. Восемьсот разных библиотек… Это нормально.

                    я бы лично конечно перевел каждое репо на cmake


                    cmake может служить костяком для системы сборки. До того как я почитал про bii, зависимости у меня получались через метод getDependencies(DDepRequest &) плагина (плагин у меня был классом, сейчас решил отойти от этого — очень не гибкий код выходит). После прочтения инфы о bii я подумал описывать зависимости через комментарии, семантически связанные с инклудами (умеет ли такое clang?):

                    //! version: [>3], tags: [o1, win32]
                    #include "myLib"
                    
  • 0
    Я бы предпочёл на его месте основанный на AST чистый макропроцессор


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

    но Eclipse в последний раз, когда я им пользовался (довольно давно, надо признаться), был ужасен настолько, что и словами не описать


    Подсел на на Eclipse ещё в универе. Выбрал его тогда по нескольким причинам. Во-первых, Eclipse написан на Java и, соответственно, кроссплатформенный. Во-вторых, он бесплатный для коммерческого использования. Сейчас понимаю что Eclipse чудовищен (особенно дебаггер, это просто ужас какой-то) и хочу перелезать на QT, который обладает достоинствами Eclipse и не обладает многими его недостатками.
  • +4
    Я выучил C++ студентом

    Страуструп не выучил, а Эрик выучил ещё студентом :)
  • 0
    Обратил внимание о емаковимописателях.
    Чаще допускаются ошибки, т.к. нормальная IDE подсказывает и подсвечивает. Компилируемых языков это не касается, но в скриптовых порой встречается не рабочий код просто открыв его в нормальной IDE, когда не все покрыто тестами, да. Или множество возможных не инициализированных переменных, весь код в подсветках, как на новый год, в нормальной IDE сразу видно. Ну и любят они ещё на сервере кодить. Не все, но большинство восхваляющих, с кем имел дело. Пусть Java IDE и тормозная, но она умнее и с этим инструментом пишешь лучше код.
    • 0
      Вы ошиблись тредом, вам сюда.

      встречается не рабочий код просто открыв его в нормальной IDE

      При работе в emacs можно спокойно запускать pylint или jslint не выходя из редактора, даже автоматически в фоновом режиме (flymake), как в IDE. Они находят кучу подобных ошибок.

      Ну и любят они ещё на сервере кодить.

      В большинстве случаев это не прихоть, а необходимость.
      • 0
        Спасибо за линк, почитаю :)
        Да, Роман, знаю, что можно настроить раб. среду, а на деле ничего не настраивают(ну не все да:), да мне туда, не по теме написал.
  • 0
    Многие думают что в C++ есть только меташаблонное программирование — шаблоны, бусты, аликсандрески разные…
    Есть еще и метамакросное. Даже на стандартном препроцессоре можно творить относительные чудеса.
    Стандартный препроцессор можно заменить — видел и использовал варианты с интеграцией в него lua кода.
    Стандартный пропроцессор можно эмулировать — flex c bisonом давние друзья многих маньяков в деле автогенерации кода.

    Так что — те-кому-надо уже давно AST контролируют. Вопрос только зачем и почему.
    • 0
      Так что — те-кому-надо уже давно AST контролируют. Вопрос только зачем и почему.


      Думаю, вопрос скорее в том насколько это удобно. В принципе, люди и на брейнфаке морской бой писали.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка