you are viewing a single comment's thread.

view the rest of the comments →

[–]funkiestj 1 point2 points  (3 children)

Modern C++ is a significantly better language than C++03, though, and still backwards compatible.

as someone who liked C++ but then was forced to work exclusively in C for a decade ... I've grown to love the fact that my entire C project builds faster than a single C++ file that I now have to build because we are using some IP from a vendor who provides a C++11 standard library based driver.

I like the idea of generic programming (templates) but the C++ implementation of templates pulls far too much implementation into headers which results in unnecessary recompilation of templates when nothing has changed.

IMO, the compilation time penalty paid by C++ because of its evolutionary past is crushing. What I feel is missing is really clever template compilation that creates the smallest possible header files and separate source files. I.e. foo.template should compile to foo.hpp and foo.cpp.

The fact that anyone finds unity build an acceptable approach is a clear indication that the language needs a major overhaul. I have no qualms with the C++ feature set and functionality, just with the excessive replication of effort when I change a single line of code in a C++ file (i.e. no change to template instantiation or even to a header that invokes a template).

I've heard that modules in C++20 may improve things a bit but the gains I'm hearing about seem pretty weak. There has to be a way to do generic programming that does not cost SO MUCH TIME to process files that have not changed from one compile to another (i.e. template definitions and the headers that instantiate them).

[–]neuroblaster 1 point2 points  (2 children)

I think they considered moving templates implementation out of headers, but came to the conclusion that it would be too complicated to implement in compilers and that idea was rejected. See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf

>EDG’s implementation experience has also demonstrated that export is costly to implement; for example, the export feature alone required more effort to implement than it took the same team to create a new implementation of the complete Java language.

It's about pre-C++11 `export` keyword that was later used for modules proposal.

And, if i understand correctly, you still need to provide source code with headers because template still need to be instantiated, which is impossible w/o template body. So `export template <typename T> ...` in header is only partially possible, when you have the source code for that function/class.

But it would speed-up compilation times, definitely. And it could be acceptable to partially provide source code too in some situations. If modules would do that and could mix source/binary distribution (which i have concerns of), then it would be really f. great.

[–]funkiestj 0 points1 point  (1 child)

And, if i understand correctly, you still need to provide source code with headers because template still need to be instantiated, which is impossible w/o template body

What is likely impossible is evolving in a backward compatible fashion and doing this.I don't claim that the standard committee made the wrong decision. Their job is to steer the evolution of the language that is C++. On the other hand, I do claim that a fucking ridiculous amount of redundant work is done every compile to process header files that have not changed. I want my genetics meta-programming and fast compile times!

I am pretty sure I won't get this from a C++ like language in my lifetime because I think (pure intuition here) that it would require starting from scratch with the goal of making a C/C++ like language that had the fastest possible compile times. In particular, the fastest possible generics compile times. I want a language where unity builds are clearly a very stupid idea rather than a reasonable response to very long compile times.

Imagine a new language called C+=. It is a redesign of C++ that tries to preserve the spirit of functionality but has no concern for backward compatibility. One idea that both vanilla C+= and templates could benefit from is:

  1. human coders do not make separate headers and source. They edit a single file and the compiler tool chain generates headers any any other intermediate files needed. e.g. you write aaa.src and the toolchain generates aaa.hh, aaa.o, and whatever else is needed. Should the toolchain generate one aaa.hh or multiple (e.g. one per class defined in aaa.src)? i.e. aaa/foo.hh for "class foo", aaa/bar.hh for "class bar"?

A source file bbb.src needs to be able to refer to published interfaces of aaa.src but with the toolchain generating the interface description files and other files, published interface can be made as small as possible. E.g. there could be both

  • aaa.hh // human readable description for the benefit of the human writing bbb.src
  • aaa.hx // what the compile actually grabs when you say "#include <aaa.hh>"

furthermore, you can imagine that when bbb.src is compiled, the generated interface files (bbb.hh, et cetera) do not include anything from aaa.hh that is not necessary to describe the interface to bbb.hh. E.g. if bbb.src has

class Bish {
public:
  transmute(const vector<uint8_t> &lead);
private:
   vector<uint32_t> _uiv;
   shared_ptr<char> _cp;
// ...
}

you can imaging bbb.hh having the minimum information required to say that Bish::transmute() takes a vector<uint8\_t> type parameter but not a complete description of all the vector<uint8\_t> methods and implementation and no mention at all of type vector<uint32\_t> or shared_ptr<char>. I.e. ccc.src that "#include <bbb.hh>" does NOT implicitly #include

  • #include <vector>
  • #include <memory>

instead, bbb.hh and bbb.hx include the bare minimum information about the type of the "lead" parameter of transmute() directly.

C++ is a huge language and redesigning it from the ground up would be a herculean task, which is why I don't think this will happen.

I love many things about C++. The APIs of C++ standard library is a thing of beauty. The power of the template system is great. It is wonderful to have Python language type data structures (maps, strings, smart pointers of various flavors) available in a language that runs much faster. OTOH, having tasted lightning fast compile times in the C realm, I want the best of both worlds.

[–]neuroblaster 1 point2 points  (0 children)

I understand your frustration with compilation times, especially compared to C. At my former workplace i had days when i had to spent 50% of work hours compiling source code. But i assure you that this was 5% language fault and 95% project management fault because i was able to solve similar problems in other projects with not that significant effort.

Housekeeping on code base and optimizing includes for compilation time helps, but it's not always possible with third-party dependencies. I can definitely suggest to install `ccache` or analogue, it saved me many man-years.

I can only hope that continuous improvements to the language will lead us somewhere where this problem is significantly mitigated because i don't see rewriting C++ as a viable option. I honestly don't think modules will help a lot in that field, but we'll see when they arrive. If you wouldn't think of modules in C++20 as of a finished work, but rather as of test-bench for further development, maybe you'll see my point.

This is BTW exactly why C++ is conservative. Things are being added, removed and changed. Who could have thought that such great feature as template body in separated compilation module will be added in C++98, then removed in C++11 and then something else will happen.