6 ms·
I think Conan and Modules will make c++ more popular in the future. It is a behemoth of a language. Very hard to master and it is still too easy to produce diff
by deutschepost 3y ago
I think Conan and Modules will make c++ more popular in the future.
It is a behemoth of a language. Very hard to master and it is still too easy to produce difficult to debug errors. So it will be very important, that the language changes to address these.
But in working with c++ day to day I feel the most annoying things are indeed dealing with dependencies and headers. It can be a pain to set up a complex c++ project on a new machine. Even with Conan it can still be a pain because configuration management is a mess in c++.
As for headers I can’t wait to see them rot in hell. Some people say that they can help you reason about your Program, but this is a very small positive point. Too many times I had problems with includes which only worked because a Translation Unit included some other header beforehand. I once read a blogpost of the developer of SumatraPDF where they describe that they never include anything directly[1]. This can be an improvement for compile time. But if someone else is working on your code or has to refactor it, it can be impossible to read yourself into it or track any compile time error. If one would only use modules these errors would simply not exist.
[1]https://blog.kowalczyk.info/article/96a4706ec8e44bc4b0bafda2d9ba502f/extreme-include-discipline-for-c-code.html https://blog.kowalczyk.info/article/96a4706ec8e44bc4b0bafda2...
- jb1991 3y agoWhen you consider that most popular modern languages long ago abandoned the idea of a separate header file, you see that the advantages far outweigh the disadvantages.
- layer8 3y agoThe problem isn't separate header files, it's textual inclusion. With C++ modules you still have separate module interface units. Separation between interface and implementation is important for enabling circular dependencies (mutual use) between implementations.
- otabdeveloper4 3y agoExcept for C, no popular language (modern or ancient) has ever used header files. So it's not a story of "abandoning", more like an insane C idiosyncrasy that wasn't ever used anywhere else.
- stabbles 3y agoIn Python I sometimes miss "header files". Quite often you see: import x class Foo: def bar(self): import y # break circular import y.something() Would be nice to be able to import `Foo` without pulling in also `y`, or moving `y` inline. Can be solved in different ways, but you see inline imports everywhere.
- colejohnson66 3y agoThat's not a problem with modules, per se, but a problem with Python's module system. Importing a module in Python just executes the whole file. JavaScript used to have this issue with `require` years ago. Each `require` statement essentially executed that import right then and there, and would bug out if circular dependencies existed. However, they fixed it with `import`. Almost every other module-based language does not have issues with circular dependencies. Python, in theory, could follow their lead, but they won't. EDIT: I wasn't as clear as I could be. The issue again isn't modules, but scripting languages that allow top-level statements at all. Intermixing types and method declarations with executable code makes circular decencies an issue. Compiled languages don't allow top-level statements, so they don't have the dependency resolution problem.
- paulddraper 3y ago> Each `require` statement essentially executed that import right then and there That still happens. It takes a lot of magic trickery to make cyclical require/imports work for JavaScript and a lot of times they don't/can't.
- colejohnson66 3y agoThat's true. I guess I misspoke and wasn't as clear as I could be. What I meant to say was: the problem with Python and JavaScript's module system isn't modules themselves, but top-level statements. You are correct that `import` doesn't solve such a problem; It solves the synchronous dependency resolution problem. Realistically, that's just what happens when a language allows top-level statements, as they are executed when a file is loaded. As such, scripting languages tend to fall victim to the problem, but compiled ones don't. I'll update my comment.
- charcircuit 3y ago>If one would only use modules these errors would simply not exist. In exchange for reducing parallelism because you are not using forward declerations to break dependency chains up.
- silon42 3y ago+1 I once refactored part of my code for headers to only #include forward declarations (and few generics, of course), except where really needed (implementation) It made compile times 2x faster, probably could get 3x if fully done.
- gpderetta 3y agoIt is going to be a struggle. Headers work well for full recompilation as they provide significant parallelism. But are very bad for incremental compilation.
- pjmlp 3y agoOnly for the mindset stuck in the classical UNIX tooling approach, module based languages have used parallel compilation for a long time. The big difference is that those communities embrace compiler and tooling are part of the same story. Thankfully now we have a tools working group trying to bring C++ community into the modern world of module based compiler toolchains.
- charcircuit 3y agoShow me a module based language that maintains the same parallelism of compiles.
- pjmlp 3y agoC#, compiling in parallel since the C++ compiler was replaced with a C# written one, beating C++ traditional compile times hands down. Go, compiling code in parallel since Go 1.19. One is able to compile the whole toolchain from scratch faster than many C++ codebases. Active Oberon, compiling in parallel via the Paco toolchain since 2003, a full graphical workstation OS, built in a couple of minutes. Ada, parallel compilation available in most toolchains since 1989. Also available in GNAT. Delphi, yet another example. It is C++ that needs to get up to date with modern toolchains and away from hacks like unity builds.
- gpu64 3y agoIt's crazy to see how much work header files make the C++ compiler do just to build hello world: $ gcc -E hello.c | cloc --force-lang=c - 419 $ g++ -E -std=c++11 hello_iostream.cpp | cloc --force-lang=c++ - 20707 $ g++ -E -std=c++20 hello_iostream.cpp | cloc --force-lang=c++ - 30876 $ g++ -E -std=c++20 hello_std_format.cpp | cloc --force-lang=c++ - 42757 Just bumping the C++ std version can add thousands of lines of code.
- nly 3y agoiostreams are more or less just a straight conversion of everything that C streams were (but nobody ever used) in to polymorphic interfaces and templates. It's a shame they add so much header bloat, but there's a lot of functionality in there and it's hard to see a way it could have been avoided if you want type safety.
- leni536 3y agoMost of the sin of iostream is having a humonguous overload set for operator<<. AFAIK it's not too bad to just compile the stream headers, but the overload resolution for `std::cout << anything` is expensive.
- phaedrus 3y agoAnd after all that effort, an operator overload is still the "wrong" API for the job anyway, because: it's missing a crucial argument! Any binary (infix) operator can only relate two things, but typically when you want to print something you actually want to relate three things: the stream, the object or value to print, and the way you want values represented. Oh, sure, you can manipulate this by inserting magic formatting objects, but that's not different from saying all functions take one argument a la Category Theory or Haskell without syntactic sugar. Or you could write a class or function that allows you to tag your object or value by changing its type to a different one so a different operator<< overload is called. In the iostreams design, you're only indirectly selecting which print function to use by manipulating either the stream or the printed object. But in actuality the types of your two arguments are not different, so either you must munge global settings on the stream or "hack" which operator<< overload is selected. And that's the crux of the issue; what you "really want" is a stream API with three arguments: the stream, the object or value, and a pointer to a function (or function object) that takes the value and transforms it to a stream of characters. Why not just pass that function directly and explicitly? Of course that requires something that's not just a single chained infix operator; my thesis being that starting with that quirky choice leads to down a path that ends in a bad design.
- mrozbarry 3y agoI think headers were a great tool from a time before intellisense where developers and teams would include function + comments on how to use it. On the flip side, I think there are still a lot of developers who don't use language servers or use the equivalent of notepad who do rely on separate header files as a means of documentation. That said, it's always been painful to structure inter-related headers and source files to avoid circular dependencies, and if modules truly resolves that, I'm happy to see it.
- cozzyd 3y agoconan2 breaking backwards compatibility with conan1 is... rough. My first conan experience was everything breaks because of that...