C++ Club - 173. Client project lessons, C++26 reflection, CMake.

Episode Date: April 5, 2026

With Frances Buontempo, Daniela Engert, Gianluca Delfino, Jody Hagins, Ivor Hewitt, Bjarne Stroustrup, and Aurelien Pora.Video: https://youtu.be/3-JKn7nF-tA.Notes: https://cppclub.uk/meetings/2026/173.../.

Transcript
Discussion (0)
Starting point is 00:00:00 Welcome to the C++ Club. This is Meeting 173. Right. First of all, I wanted to mention one of us who we lost Raina Grimm. Sadly passed away in October last year. I didn't know him personally, but he seemed to have been a great guy and an excellent C++ educator. And it's a sad loss. I've met him a couple of times at different conferences and you're absolutely right in your assessment. It's so unfortunate. Maybe I may give you the information
Starting point is 00:00:43 that his son is trying to keep on with this block here and I might appear there sometime in the future That's good to hear. That's good news. Thank you. Hopefully his life work continues this way. Next item is a bit of a feedback reaction. Last time, which was a very long, long time ago, I mistakenly said that C-Make was a product of the company called K-Dab. Obviously, that was wrong. I'm correcting my record. It's, of course, kitware.
Starting point is 00:01:34 And we'll talk about C-Make later. Other news, I have a blog now. Yay, it's pretty much empty, except for one record. Sort of an explanation, why it took me so long to restart. the meetings. I've been on a very intense project since the last meeting. The project lasted for about a year and a half. It was a really, really interesting project. Now that it's over, I wanted to mention what I was doing there. I was brought in to implement a particular piece of infrastructure. I expose an internal system to clients.
Starting point is 00:02:19 using a web service. And while I was doing that, naturally I tried to optimize the build system, as one does, made it quicker than before. That particular codebase built in seven minutes before I started with it. And after that, it was less than half a minute. Obviously, I cheated a little bit with C-cash. anything to make the build quicker. And then I was extended to do the same build improvements in another codebase.
Starting point is 00:02:57 Did you use any particular tools to analyze the build times? Later on I introduced Clang Build analyzer and that helped pinpoint parts of the code that the other developers then looked at. But my main objective, apart from the actual main one, was I wanted to introduce static checking because they only had pretty much a single build using Seamake, and that was either release or debug depending on what configuration command you run last, everything built into the same build directory, which was inconvenient. And also in the other codebase, they did something I never encountered before, which was they built their test binaries into the source tree.
Starting point is 00:03:58 And that was not ideal. That doesn't sound, right? Yeah, it was not ideal. My goal was, first of all, to enable different build types in such a way that each of them built into its own build directory, build tree. My idea was that if I had that, I could then set up a continuous build in such a way that all those builds could be done in parallel, because they would not be interfering with each other. But in the second codebase, that wouldn't be possible because the test binaries would override each other. There would be race conditions in the file system, which I didn't want. I can see why you're experimented with Basel.
Starting point is 00:04:46 Did you have to then go back to Seamake, I see here? They only used Seamake. As often happens with Seamake, you just Google a working configuration, then you cut and paste lots of stuff, and you then don't touch it because it works or you think it works. You hope not to touch it. Or you hope it works. And slowly over time, it grows very much.
Starting point is 00:05:12 various appendages and strange build commands that you have to run. So unpicking that took quite a long time. But in the end, I had builds that used Seamake profiles, which frankly saved me. It was such a great life quality improvement for anyone who works with Seamake. I came up with this scheme where the profile name. expressed the build flavor, so to speak. For example, I had a build called GCC underscore debug, Deb, and GCC rel. And then I also introduced Clank compiler.
Starting point is 00:05:59 The production was GCC, but I could run Clang Build in parallel. And that enabled me to also use all the Clang tools, including Clang Tidy, all the Clang sanitizers alongside GCC sanitizers. I was lucky that they stayed on pretty much the latest compilers. So I think by the end of it, we used GCC 14 and Clang 19. Well, not the cutting edge, but still pretty new. Better than the average of the industry. Yeah, definitely better than many.
Starting point is 00:06:38 So yeah, by the end of that exercise, I had those builds running in parallel. Those included debug release, all the sanitizers, sorry, not all the sanitizers, address undefined behavior and thread, setting up memory sanitizers and exercise and frustration, so I didn't do that. Did you have Valgrind on the side? Another build was released with debug information for Valgarind. Everything was running on Jenkins. And yeah, the entire build set took about an hour.
Starting point is 00:07:16 That's pretty good. Yeah. And I scheduled it once a day at night so that it didn't interfere with any other builds. The first codebase was one and a half years old. The other one was more than 10 or even maybe 15 years old. C++ plus 23 was enabled in both. And it's not like everyone suddenly started using those SQLSysc 23 features, but if anyone wanted to, they were there.
Starting point is 00:07:45 Like, string contains, oh my God, imagine that. Most new features were in use, especially concepts. That was nice. That was my first time dealing with using concepts, and I really, really liked it. There was quite a lot of template code. I decided after some Googling to use a Drogon framework for creating a web service. That was really nice. And I combined it with some templated code to make it easy to add new endpoints.
Starting point is 00:08:20 It was really quick and easy to set up. And the benchmarks show that Drogon is one of the fastest available C++s web frameworks. So, yeah, if you need... I didn't know about this Drogon. Is it like a header only perhaps thing or is it something? Let's see, I don't think it's header only. I think I had to build it and set up it as a library dependency. That's actually good.
Starting point is 00:08:49 If you want to increase build times, use header only libraries. In fact, I wanted to ask you, what was the biggest bang for your buck when you wanted to reduce the time for compilation? Did you find that too many includes or perhaps the any templates were the problems or a combination. Circular dependencies were the biggest culprit for long build times. I found an interesting thing about Ccash. Apparently, the new version of Ccash, starting from version 4, supports remote cache in the
Starting point is 00:09:24 same format as Basel. So if you have a Basel cache server running somewhere, you can use it alongside Basel for any CCAC remote storage. There is an option that you can set up and it works out of the box. The whole thing was a lot of yak shaving. So in order to do one part, I had to set up a basal build of a framework called TensorFlow. It's like a machine learning thing. I think it's by Google and obviously it uses basil.
Starting point is 00:09:59 And they didn't have Basel, so I had to onboard it. And then I discovered that the full build of TensorFlow took four hours. So after that, I had to set up a remote cache, which was fairly easy because they used Docker infrastructure. And I just found a Docker image with a ready-made Basel cache server. Then we pointed it to Amazon AWS. And by the time I left, I was plenty of space. left in that cache.
Starting point is 00:10:31 And then, after that, I discovered that Ccash supported it as well. So the interesting result of it was that often local cache in Ccash was slower than using the remote one. I suspect that might have been because the local storage was getting full and was just thrashing, trying to clean up and then that potentially slowed it down. I have to mention that both projects were in teams that were working close together, and both teams were excellent. They were really easy to work with fantastic experience working with them. So the last thing that I did was I tried setting up modules because by the time my consulting gig was up, I had a couple of weeks left and everything was pretty much done.
Starting point is 00:11:29 So they said, why don't I look at using modules? And sadly, GCC-13 had a few bugs and just didn't work. So I left it all more or less prepared for them for when they migrate to GCC-14, and then it all should work at least with a single project. The goal was just to convert a single part of the project to modules and see how it goes. So, Clang 19 worked perfectly. Did they have a specific goal to try and get modules working? Was it working in other stuff?
Starting point is 00:12:07 Or was just wanting to experiment with something that probably should work by now? It was the latter. They wanted the latest feature. They knew all the advantages of having modules. And I'm guessing the most sought-after feature of modules was code isolation and organization. not the build time speed up. The main thing was to use modules to make it all tidier and more isolated and prevent further circular dependency from appearing. Good approach.
Starting point is 00:12:45 Yeah. And they just wanted to prepare for the future. I was glad to see that they stayed on the latest compilers. And their internal systems were easy to work with and upgrading. infrastructure-related stuff was pretty easy. So, yeah, C-Make is a terrible mess, like I like to say, and everything I learned about it was against my will. My advice is to use C-Make presets.
Starting point is 00:13:13 They are supported by VS code out of the box. And if you make C-Make presets, sort of the first-rate citizen of your build, the source of truth, that gives you the ability to, repeat builds both from the terminal and from VES code. The build artifacts go in the same directories, so you don't end up rebuilding stuff as you switch from terminal to VS code and back. That was my first time working with Docker and Dev Images,
Starting point is 00:13:51 and I really liked it. When I was being onboarded after an hour, I could build the entire code base with all the debugging and stuff. So for me as a consultant who goes from firm to firm, that was like a thing unheard of. It usually takes days, if not weeks, to get onboarded properly and start building and committing. And here I am in my first day opening a PR pretty good. I worked in finance for a bit once, and my first contracting role it took, weeks to be able to
Starting point is 00:14:28 commit any code. But it was the same problem. All the other people went, it builds on my machine, but there were circular dependencies going on and they just walked himself to a point where they'd got an old DL that he kind of bootstrapped itself. And it's when we started
Starting point is 00:14:44 trying to set up CI, it became apparent what was happening. And we managed to fix it as well and get it down to you be able to build something of a lower circular dependencies again, honestly. When I came on the project, their initial structure was in the source tree, you had multiple projects. Every one of them had their own C-made lists.
Starting point is 00:15:06 There was the main one in the root of the source tree. And the thing that was the culprit was they added the source tree root directory as they include to all the projects. And so every project was free to include anything from me. anywhere. And obviously that wasn't ideal. It resulted in lots of circular dependencies. As for the IDE, they preferred VS code. I initially dismissed it because it's a browser. I mean, JavaScript-based IDE for C++. Come on. But it turned out it was pretty good, especially because it supported dev containers much better than, say, Sea Lion. Till I left,
Starting point is 00:15:56 I couldn't get C-Lion working with dev containers, no matter what I tried. It was always broken in different curious ways every time I tried it. So I stayed with VS code. I think most of the people I speak to, they have similar opinions. We all came to VS code with suspicion, thinking that cannot be for me. But then there is a divide. Some people are the hardliner. They will stick to VIM and Emacs.
Starting point is 00:16:26 more power to them. Otherwise, for common mortals like myself, I think VES code comes with batteries included. Everything works out of the box. It's fast enough. Certainly it's not slowing me down. My own brain is a bottleneck here, not VS code. So it's good enough to me.
Starting point is 00:16:47 Yeah, yeah. So this was the first time I used Moldlinker. If you haven't used it, I strongly advise you to try it out. It's a drop-in replacement for the Gold Linker and LLD, and it's so much faster than anything else. Even faster than LLD. It's really good. The guy who created it was the same guy who worked on LLD. C-Cash with remote backend and DISTCC also helped.
Starting point is 00:17:18 We only had one DCC server, but it was a pretty powerful one. Clang Build Analyzer. although getting useful results with client build analysis is more difficult than tweaking the build because it usually requires quite a bit of refactoring and getting rid of unnecessary templates and stuff like that. So it's more of a strategic engine that can advise you what to look at. One other feedback was that the release process must require as few manual steps as possible. And I made it my goal to set it up in such a way that build would only require at most two commands, one to configure, including running the configuration stage of Seamake and the other one to build.
Starting point is 00:18:10 Clang format. I set up Clang format. Yeah, Kubernetes is great if you are a YAML developer. Were you using Kubernetes just for your build flow or West. it actually being used for deployments? It's deployments, yep. So all the prod applications were running through, they were all containerized.
Starting point is 00:18:34 Yep. Interesting. I hadn't talked to anybody in the space that was actually using it because the tests that they had all done, even though the performance was negligible, but it was measurable, and they didn't want to pay the cost for it. So was that an issue at all, or has that been solved? I don't think performance was a huge bottleneck in that particular setup.
Starting point is 00:18:58 Most of the clients used Python, so it wasn't like C++-based code running in a container would slow them down. In those cases where there was a slowdown, it wasn't because of the container, but because of the problems with C++ implementation, for example. But the deployment was a breeze. It was very easy. When I came on a project, I was like, so do you have a team that does your deployments?
Starting point is 00:19:30 And they smiled and said, nope, we just do it ourselves. Just edit one YAML file and it's done. I'm surprised I didn't look at you and said, now we do. They did prod deployments several times a day, all by themselves. If anything went wrong, they just revert. to a previous good version. And it's fantastic. I really liked it.
Starting point is 00:19:55 Right. Let's go to the next item. A brief history of Bionnus Strohstrup. Biannestroostop. He explains how to pronounce his name in this video. It's a short video. I liked it. It's a good production value.
Starting point is 00:20:12 Very lighthearted. It was funny. Yeah, it was pretty funny. I found it very humorous. It was nice. And they are, they're going to. to produce another one about C++, I think. Feature length one or another small one again?
Starting point is 00:20:25 I don't know. It's like the next step probably in the history of Vienna. I bet that one would be fun. Right, Jean-Luca, this is you. I have to change that picture, though. So thank you for warning me that we were going to talk about this. I remember writing this last summer. And I was pleased that somebody else posted it.
Starting point is 00:20:50 I thought it was going to get just ignored and got a few upvotes on the sites. I mean, you know, got a couple of good, very good tips, which I implemented. And overall, you know, I was pleasantly surprised. So I think, you know, I dip my toe in the reflection feature and I couldn't get enough of it. certainly I would suggest anybody to play with it. Sorry, for the podcast listeners, can you say what the title was? All right. So I implemented a little reflection-based program that would produce a UML diagram
Starting point is 00:21:36 at compile time with some cheating. And obviously it's not supposed to be a real implementation of anything, and just a bit of a toy program that would navigate the tree of your classes and output something that is plant UML script that you can just and plop into a viewer and produce a diagram of sorts. So it's an experiment, but it taught me a couple of concepts and I had fun writing it. So definitely, definitely suggest everybody to play if they can with reflections. Unfortunately, we at work won't be able to for a while, so we are far from the latest compilers. But if anybody can, and maybe people in other industry can, then go ahead.
Starting point is 00:22:34 Please. I don't know if you're going to also talk about some talks that did a very good job at explaining reflections much better than I. could in my post. There was a Barry Resvin talk in CBP gone last October. That's great, but there's a bunch of them. There's herbs at this talk. It'll be one of the next times, not this time. Jan Lucas article is titled C++26 Reflections, Adventures and Compile Time, UML. And there is a page that you link in Compiler Explorer, which shows the execution and the result of it.
Starting point is 00:23:18 And it's really amazing. It was amazing how easy it was, and how much I can now get away without learning proper metaprogramming. You said your experiment had a bit of cheating. I would say reflection is sort of cheating. When the program reflects You get the key to the kingdom.
Starting point is 00:23:43 Yeah, exactly. It's like a meta world. Has anybody seen the latest fought block by Ben Dean? Oh, no. He was speaking about reflection and the limited ways of code generation that is coming along with it in C++ plus 26 is actually capable of doing type calculations. in the reflected world. So yay, no more template metaprogramming to calculate types. This is amazing.
Starting point is 00:24:21 Does this mean computing unique types or does this mean like being able to generate, for example, a strong type for an alias? It was more general. It was about the fact that you can use only template metaprogramming if you want to compute something along with types. We have value-based meta programming. This is a pretty old kind of thing with const-exfer now, but with type calculations, we couldn't do that with the facilities in C++ up and until 23.
Starting point is 00:25:00 But with 26 and reflection, we can actually do also type calculations in the meta world without using templates for that. Because you know templates require memorization and specializations, and this is really expensive to the compiler. So now we have everything we need to actually write complete programs within the space of a compiler. That's interesting. Can you at the same time, can you also tell whether the class has been defined or
Starting point is 00:25:35 whether it's incomplete or not? I didn't really understand what you were trying to ask. What do you want to repeat? Currently, you can't tell in the language if a class is defined or not, right? If a type is actually defined or not or if it's just aliased. Hmm. And because there's a lot of template things that require the class to be defined for it to have defined behavior. But you can't tell currently.
Starting point is 00:26:06 at compile time. And I was just wondering if maybe you could do that with reflection. So you mean you speak about if you can sniff out at compile time, if a particular specialization has happened before? Well, no. So let's say you just have struck-fud, semicolon, you've declared it, but you haven't defined it. Okay.
Starting point is 00:26:27 That's what I want to be able to know if I'm looking at a type, has it actually been defined or has it just been declared? I would try the eyebrow operator to actually bring this particular expected type into the meta space and see if it fails. I don't know if it's possible, but I haven't had any chance to actually play with reflections so far. But Chan Luca will probably jump into that. I don't actually know myself. Of course, you know, again, I think there's so many things. I don't know that I feel so ignorant, just looking at the many things that one could do if we just manage to master this feature in general.
Starting point is 00:27:14 I've seen about this just recently in the practical, I think the talk was called practical reflection or practical user reflections by Barry Ressing. And he would just declare the class and then open a constable scope to define it with some metaprogramming logic. I know, obviously that doesn't answer Jory's question. Yeah, no, for that specific one, if you, if for that specific one, if you've got just a declaration, when you then in the reflection, if you then, you've got the option you can iterate over the, over the contents. In that case, if you tried iterating, it would be empty. So you could have a bit of logic there to say if there's nothing to iterate,
Starting point is 00:27:57 with the iteration of the is not, then it is. So it won't fail, it'll just not, it won't have any elements. Exactly. It wouldn't distinguish between an empty class and a. Yeah, I'm not sure. I'll have to dig to find out if there's a specific way to then dig further. But yeah, that was one way that, yeah, if you try to iterate it, it would be able to see. But yeah.
Starting point is 00:28:17 But yeah, interesting. I'll dig into that and find out. So John Luca, with this example that you were talking about the Barry had, does that mean that at compile time with reflection, I could define a type, and then I could iterate over another type, like I could say, you know, define a type name. And basically, I just wanted to act just like a string, except I wanted to be in other words, a native strong type. And then I could just iterate over the string and pull everything from a string into that guy's space. And now I've got a new strong type that acts just like a string.
Starting point is 00:28:51 Yes. So you have, and do look at the full implementation, a full example. in the video that he presents, you know, it's honestly mind-blowing, is building these classes on the go by just declaring the type. In this case, in his case, it's declaring a little bit of a vector class. And then, you know, it just goes declaration, then cost of a scope, it adds on top that whatever it wants. And after the scope is done, the type is defined.
Starting point is 00:29:20 And in the scope there, it did marvelous things, you know, all sorts of backwards flips. that blew my mind, honestly. Do you know which talk this was? Yeah, it was practical. Let me just look at it. Practical reflection with C++26, Barrett-Refstein, CPPC-B-B-C-C-V-T25. And Jody, to your question regarding the existence of a particular type,
Starting point is 00:29:45 I think you should be able to do that in C++20 with requires expressions. Yeah, no, yeah, I don't think you can. I've been down this road with some other folks before. But I would love to see that. There's the problem, the problem is that if you do it, is that the memoization, once you've decided whether it's defined or not, that will change once it becomes, like if you say, oh, it's not defined. And then later, if you ask, and it has to change to be defined. And so there's a chicken and egg problem there and actually determining at which location because of the memoization. I didn't speak about this memorization kind of thing because you were asking about a non-templated class.
Starting point is 00:30:32 And in the case of a non-templated class, it should be possible to do it with a requires expression. You ask for the existence of a type and it should just fail to give an valid expression in there. And now you should be able to actually say that the attempt, do that requires it be evaluated to false. We can do some experiments probably and see that. Yeah, that's what I'll be doing when we hang out. Thanks. Oh, Biona. Hi Biana. Thanks for joining. Hi, I thought I'll just hop in and say hi. I mean meetings until now and from 10 minutes from now. Just to say hello. Thank you.
Starting point is 00:31:29 We were just discussing a video about yourself, this one. That seems to be popular. Yeah, the general consensus is that it's a pretty nice video. It's quite funny and good production value. So looking forward to the next one. There will be one on C++ in May. It's really nice. And you did explain how to pronounce your name, so that's good.
Starting point is 00:32:00 Yeah. I mean, 20,000 views a day on average for the first couple of weeks. It's pretty amazing. Yeah, they did a good job, I thought. Yeah. One thing that Fran mentioned was this about CPP reference, that there was a case of a vandalism. It was some time ago, but since then, it's been put in read-only mode,
Starting point is 00:32:34 and so there's no new C++-26 content there. You're working on it. It's been like that for over a year now. There's a little banner up saying they're working on it, and there was an email that you could send support to, so I did, but it's been the same state for over a year. a year now, which is unnerving, I think. Yeah, it's really sad.
Starting point is 00:33:00 Everything has been superseded by Rust, according to this troll person who did it, vandalized it. Okay, it was pretty childish, but the results is still that we don't have a reference at the moment. But we have alternatives. We do. There's no CPP dogs. For example.
Starting point is 00:33:21 Yeah. But they say it's based on the content from CPP reference. So presumably there won't be anything new. Although they do have a C++-26 filter. I don't think the filtering works at the moment. I couldn't get rewriting. I just sent a message asking. Right.
Starting point is 00:33:43 Yeah, hopefully it'll be revived at some point. Or maybe this one grows. it'd be good to have a point of reference somewhere. Well, otherwise you'll have to read the textbooks which are well on paper mostly and not organized for look up and all the standards which is unreadable for ordinary mortals like me. I bet someone is going to try and ask Chad GPT to summarize C++ standard and we'll end up with a couple of of pages of Njibirish so that's good. Either that or it'll burn down a couple of the extent.
Starting point is 00:34:26 A couple of burnt lakes later. We'll have a couple of pages that are useless. Yay. Yes. So I promise to talk about C-make, if you're not still too bored of it, seems to be everywhere. And this one is a bit outdated. I would like to listen to this, but I can't. I have to bail out again. I promised us to come and say hi. Thank you very much for joining, if only briefly. I'm sure I wasn't the only one who hoped that C-Make-4 would be a major improvement, to the point that someone on Reddit said, it's new major release because they completely overhauled the language to be more readable, right?
Starting point is 00:35:14 Right? What are you in version numbers? They seem to be using them very arbitrary. Really? It's like, C-Make 3.28 adds support for C++ modules. C-Make 4-0, minor improvements. I mean, of all the build systems ever created, C-Make is certainly one of them. You know that C-Make still hasn't any support for header units, which means half of the modules feature. And it's not like all other build systems are perfect.
Starting point is 00:35:48 It's like the other build systems that do support modules that come to mind are MISON. I'm not even sure about it. MISON is a big critic of modules. Oh yeah, I read his blog post. He seems to be very against it. And he seems to only focus his attention on the build time improvements of modules. I think it was some other. person's contribution to the MISON codebase to introduce, that introduced some basic support for modules.
Starting point is 00:36:26 And that's pretty much it, except... We have multiple alternatives. X-MEC is the biggest one. X-MEC. Yes, I'm very fond of X-Make, because in my personal toy projects, it removes all the friction that usually is associated with the build system, and it just works. I hadn't tried its module support yet, but... From what I read in the documentation, it's been there for several years now, and it's only getting better.
Starting point is 00:36:56 I'm using MSBuild, and MSBuild is working like a charm for many, many, many years now. Unfortunately, you can't use it. Like I was going to mention on the feedback of my last project, that life is pretty good if you don't have to build for Windows. We only build for Windows. We have no troubles. I think the trouble starts happening when you're trying to build for more than one platform. So it depends what you're coming from. But it's not insurmountable, but yeah, it adds challenges.
Starting point is 00:37:32 There was a talk by, I think, Bill Hoffman, who is one of the main people or maybe even the person behind Seamake. and the talk was 25 years of C++ build portability. And the comments are brutal. The first one, I don't understand how we accept C-Make. The fact that Bill Hoffman tends to apologize for C-Make design in all his presentations makes me feel bad for him. But at this stage, what can you do?
Starting point is 00:38:09 I mean, one of the ways forward that I can see would be to treat C-Make as sort of an assembly language for the build and use C-Make file generators like X-Make to produce C-Make files and then build with C-Make, introducing one more layer of indirection, which, as we all know, is a solution to everything. Yeah, I mean, that's effectively what I used to do when, I mean, it's a long time again when we were doing KD developments.
Starting point is 00:38:36 It was, effectively, you used the QT profiles, the PRV files, and they would then generate the CMake file for you. And I was quite happy using CMake. It just worked, but you never actually touched it yourself. You work at a level above defining the QT files, and then that spits out C-Make. This is the way. I think we're out of time.
Starting point is 00:38:57 I wanted to show you this post on MasterDon, where someone said, C-S-C-++, a compilers are a tool to convert source code into undefined behavior. and there was another one. I'm a full stack developer in that my stack is full, and if you try to push any more tasks on me, I'm going to overflow it and start corrupting my own memory.
Starting point is 00:39:21 Right, I think that's it for today. Thank you very much for joining, and I'll see you next time, hopefully soon. Bye, bye. Cheers.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.