CppCast - JSON for Modern C++

Episode Date: May 3, 2024

Niels Lohmann joins Timur and Phil. Niels talks to us about his popular JSON library, JSON for Modern C++ (often just known as nlohmann/json, after its github repo). We chat about the history and purp...ose of the library, with an interesting aside into starting and maintaining a popular OSS library, as well as what Niels is up to today. News "The Performance Impact of C++'s final Keyword" - Benjamin Summerton Reddit discussion Kris Jusiak: Meta-meta programming! (Reddit) Links "Tips on Surveying the C++ Community" - Anastasia Kazakova's talk JSON for Modern C++

Transcript
Discussion (0)
Starting point is 00:00:00 Episode 381 of CppCast with guest Nils Lohmann, recorded 29th of April 2024. In this episode, we talk about whether the final keyword makes your code faster. And about meta-meta-programming. Then we are joined by Nils Lohmann. Nils talks to us about his JSON library. Welcome to episode 381 of CppCast, the first podcast for C++ developers by C++ developers. I'm your host, Timo Dummler, joined by my co-host, Phil Nash. Phil, how are you doing today? I'm all right, Timo. How are you doing?
Starting point is 00:01:04 I'm all right, too. How are you doing? I'm all right, too. I'm quite busy. I just recovered from ACCU, which is the conference that we were both at very recently. Now the next thing comes around as a mailing deadline for the St. Louis committee meeting coming up in two weeks is the mailing deadline. So I need to finish a bunch of papers. And yeah, what else is going on? Oh, CPPCon. the mating deadline so i need to finish a bunch of papers and yeah what else is going on oh cpp con the talk for the call for submissions is going on and i'm the program chair this year so there's
Starting point is 00:01:30 a lot of stuff to deal with uh while that's happening so yeah busy very busy but otherwise great finish spring is finally here it's uh it's warm uh the snow has finally melted two days ago and like there's suddenly flowers and leaves and all kinds of green things and it's great um so yeah it's i'm in a good mood because the weather is nice um how are you phil uh well you mentioned about recovering from accu i don't think anybody ever truly recovers from the accu conference it uh it went well as we said before it's my first time on the organizers side and everyone came up and told me how great it was. It was really good.
Starting point is 00:02:08 And how much I enjoyed it. So quite a few actually said it was their favorite conference on the circuit. And some of those do go to a lot of conferences. So I've got high hopes that next year we're actually going to be bigger because it has been a bit slow sort of coming out of the pandemic, getting back to its previous size. So I think it'd be good if we get more people along. It is a fantastic conference,
Starting point is 00:02:28 and it was a fantastic edition of that conference. So congrats, Phil, for doing a really good job. I'm looking forward to next year. Yeah, me too. Despite what I said about recovery. All right. So at the top of every episode, we'd like to read a piece of feedback.
Starting point is 00:02:44 This time we got an email from Michael Price. He told us that we may have incorrectly interpreted the C++ survey results we were talking about last time. We said last time that 33% of people use something other than GCC, Clang, or MSVC as their primary compiler, which I thought was a very weird number number and we discussed that a little bit. But however, Michael points out in his email, the 33% of people using custom compilers as their primary is incorrect. It's 33% of the people that indicated
Starting point is 00:03:16 any use of a custom compiler use it as the primary. That is only 40 people out of around 1,100 that participated in the survey. So actually less than 4% of the community uses the custom compiler as their primary. This is always confusing, but hopefully it sheds some light on the odd result. Thank you very much, Michael. That indeed explains the number. I think it makes a lot more sense with your explanation.
Starting point is 00:03:38 So yeah, thanks. Maybe that's a good moment to actually plug a talk that Anastasia Kazakova did last year. What was it called? It was called... Surveying the Community, was it? Tips on Survey. Yeah, Surveying the C++ Community or something. Where she actually went through like, here's how you interpret all of your survey results.
Starting point is 00:03:58 And we have these three different big surveys in C++. And here's why they're different. And here's how to like read between the lines and stuff like that. So maybe I should have watched that talk again before talking about the survey results on the podcast because it's indeed sometimes tricky to interpret these numbers correctly.
Starting point is 00:04:20 All right. So we'd like to hear your thoughts about the show. You can always reach out to us on xmastered on LinkedIn or email us at feedback at cppcast.com. Joining us today is Niels Lohmann. Niels is a software engineer with nearly two decades of experience in C++ and Python. He began his career in academia, developing memory-critical verification tools, and earned his PhD from TU Eindhoven in the Netherlands and the University of Rostock in Germany. In 2014, he transitioned to the automotive software industry where he worked
Starting point is 00:04:50 on a variety of production projects, including embedded navigation libraries, streaming data backhands, and most recently, in-car games. He is best known for his development of JSON for modern C++, an open-source C++11 single-header library to use JSON as a first-class data type in C++. This project ranks among the top 20 most popular CSS projects on GitHub and is utilized across various industries, including the big five tech companies, automotive, gaming, and aerospace. He lives in Berlin and currently works as an engineering lead for a German automotive company, where he manages an awesome team developing immersive apps and games from Mercedes-Benz.
Starting point is 00:05:26 Niels, welcome to the show. Welcome. Thanks for having me. Yes, you said that you work a lot in the automotive industry. Have you had to work with MISRA at all? A bit, but we're fortunately a bit up the stack. So we're, as you heard, we're doing games and for games, they're not, right now they're not safety critical, so we're doing games. And for games, right now, they're not safety critical.
Starting point is 00:05:46 So we can ignore that. And we're using C Sharp. So we're using Unity. So I think there is no MISRA version for that as well. But yes, I have colleagues who are exposed to MISRA and they don't like it too much. Yeah, I hope the in-car games are not mission critical yet. My son sometimes played his driving game in the car when it's parked.
Starting point is 00:06:08 But when they're turning the steering wheel, it's actually turning the physical wheels as well, which can get me a bit worried sometimes. So maybe, maybe there's a connection there. Yes, so the steering wheel, we also use it, but also only when the car is parked, of course. But I think it will all come together once cars learn to drive without drivers, then gaming will be more important. But yeah, right now it's all fun and games and not so much worrying to all the critical things. Good to hear.
Starting point is 00:06:36 All right, Niels. So we'll get more into your work in just a few minutes. But first we have a couple of news items to talk about. So feel free to comment on any of these, okay? Okay. So this time we only literally have a couple as in two news items there wasn't quite as much super exciting stuff going on the last two weeks in c++ apparently as there is in other times or maybe i've just missed something but i got two things here one is a blog post by benjamin summerton called the performance impact of c++
Starting point is 00:07:05 final keyword and uh there's also a finally yeah there's also a discussion on reddit about this as well and uh the question is does adding final as in the keyword that says you can't like overwrite this or inherit from this uh does it make your code faster or slower and i was first a bit baffled by this because i didn't expect this to make any like difference for performance at all but it turns out that multiple blog posts which are linked in that blog post as well claim that it can actually improve performance because it can enable uh de-virtualization which is a type of optimization that can have a performance impact, but some compilers do. But a bunch of people were claiming, yeah, so if you sprinkle final over everything,
Starting point is 00:07:52 the compiler is going to devirtualize your calls and everything's going to be faster. But nobody actually published an actual benchmark. So Ben went ahead and actually did a benchmark, which I think is a really cool approach and a lot more people should do this. And so his results are interesting and kind of mixed. It turns out that it's highly dependent on the compiler and the platform. So he saw some benefit from adding final on GCC, but a slowdown on Clang
Starting point is 00:08:16 and maybe also Microsoft compiler, depending on how you squint at it. There's pretty much no effect on Apple Silicon, which is also interesting. So it also seems to depend on the hardware architecture. And his recommendation in the end is don't use final, it's too inconsistent, it sometimes
Starting point is 00:08:32 makes your code slower and sometimes it makes it faster and you don't really know. There's also some discussion on Reddit about this where people are saying he kind of missed the point because the particular piece of code that he benchmarked, like the places where he added final weren't actually places where you know the compiler could see that it could de-virtualize
Starting point is 00:08:51 anything so it might be that like the differences in benchmark are actually explained by something else but yeah there's a discussion on this uh i think it remains to be seen but i think just regardless of the results or you know whether the benchmark like the code was like indicative of the particular speed ups that we expect to get from a final i think it's just so great to see that people are actually doing this thing of hey somebody claims that if you do this your code is fast so nobody benchmarks it so let's just benchmark it i think i think it's a approach. So thank you very much, Ben, for doing this. Yeah, and I don't think we've heard the final word on this.
Starting point is 00:09:29 Yeah, we haven't. I have a feeling we're going to come back to this topic on the show at some point. I love this. I love it so much. The keyword is there for a decade now, and it seems like nobody bothered to question. I wouldn't know exactly what's in the documentation.
Starting point is 00:09:48 I read about it first, but I always had the feeling it's also about performance. And it seems that, yeah, of course, why not? Nobody looked at it. And now we have it. And now people are blaming the benchmark, blaming the question, blaming the compilers. So it seems he really put, yeah, how to say, now more people have questions and more people look into it.
Starting point is 00:10:10 And that's amazing. Yeah, I think that's good. There's quite a few more keywords like this, I think, in the language in particular. NoExcept is one that I would really love to see a benchmark. It's another one where everybody claims, oh, it makes it go faster. But I've never actually seen a benchmark proving this. And I've seen a bunch of benchmarks that are saying like showing that it actually has no effect whatsoever. So.
Starting point is 00:10:30 Although I think no except as a phonier one, because there's so many caveats to it. Whereas with final setting aside any performance implications, there is a, an actual design aspect to it. You know, you are conveying information by marking this as final, that at least to other programmers, maybe the compiler as well. So that still serves that purpose primarily. It's also worth looking to see whether that information to the compiler is valuable in terms of making performance optimizations
Starting point is 00:10:57 as well. And that part, maybe there's still more to be seen. I like it as a means of documentation. So I really would like to have more keywords. I mean, be careful what you wish for. More keywords to describe the API and then perfectly could be ignored by any compiler, but could somehow be enforced by checking tools.
Starting point is 00:11:17 So for me, final, I hardly use it, but when I use it, I would never care about performance. It's more about like, listen, please don't use this class other than I designed it. So that's fine. But I wouldn't blame any compiler developers that they don't pick up the potential performance here. So let's see where this develops.
Starting point is 00:11:38 All right. So the other news item I have for today is a post by Chris Jusiak, who is known as somebody who does really crazy things with compile time programming. I've seen him give quite a few talks at conferences that kind of blew my brain in terms of like what he does at compile time.
Starting point is 00:11:57 And this one doesn't disappoint. It's a post. I'm just going to read the first couple sentences. So it says, reflection for C++ proposal P2996, which is, you know, we've talked about this on the show quite a lot. It's like a very hot topic right now. It's very powerful. It also supports stateful metaprogramming, which ironically allows to implement at least partially the metaprogramming model of the proposal itself. Metametaprogramming. meta meta programming so basically he is implementing p2996 using p2996 which is kind
Starting point is 00:12:27 of mind-blowing and interesting even though maybe not immediately practically useful but it caught my attention yeah echoes of the last episode with with sybrand where he was talking about the uh the tearing completeness of the um one of the dwarf parsers and we determined you can actually write a dwarf parser within the within the dwarf parser or something like that so yeah but this is a compile time right right yeah well that was a debug information time so maybe that's right another level together okay so so compile time is through complete debug information like debug symbol resolve time is touring complete yeah is the linker touring complete can we do something with the linker i'm sure we can it has the linker scripts
Starting point is 00:13:13 right that's the thing yeah maybe you can do linker metaprogramming you should look into this film yeah yeah absolutely all right so um yeah the news section was a bit shorter today we're already through um and that brings us to our main topic for today, which is our interview with Niels Lohmann. Hello again, Niels. And thank you so much for coming to our show. Once again, thanks for having me. because I think almost every software project I ever worked on used your library. But then eventually we were like, oh, wait, but there's a person who wrote this. Let's try and get him on the show. So delighted that you actually made it here. Thank you so much for being our guest today.
Starting point is 00:13:57 Thanks for asking a second time, because apparently my email server bounced one of your requests. So it's good that you tried again. Yeah, so talking of names, the name of your library on the website is Jason for Modern C++. That's your official name. But everyone else seems to call it NNomanJason. So have you got used to that now? So when I first, the thing had no name.
Starting point is 00:14:23 It was called Jason because we had initially a JSON header, of course, and you wanted to give it a name. But at some point, I had to upload it on GitHub. And my username on GitHub was at that time my university username and Loman. And I just use it because it's usually not taken and I could just use it. And then I wanted to give it a name. And at that time, Scott Myers was writing his book, Effective Modern C++. And he's, to me, coined a good term of not coming up
Starting point is 00:14:54 with C++11, C++14, but just call it modern and call it a day. And I thought, well, I'm using C++11, so why not using this? May not be the best name but it's there and now it's impossible to change and it's very difficult for other people to read this and loman if you don't know that it's part of my first name and my second name then you read loman and that's not helpful but yeah i'm not going to change it now so the official name of the library is jason from what on c++ that's what we're supposed to call it? Yes.
Starting point is 00:15:27 Okay. So you said that you use.NET, C Sharp in your projects. And I don't know if it's still the case. It's a while since I've done C Sharp, but the universal JSON library for C Sharp is Newtonsoft, I think. I'm not writing C Sharp myself. I'm leading a team and they're doing it, but they were, they were cursing when I had to use Jason the first time and they're using some kind of open source library and they make it a lot of fun. Like why can't you write something? I said, no, no, no, I'm not, I'm not helping you here. So I'm not, I'm not sure what
Starting point is 00:15:59 they're using inside. Yeah. That seems to be a bit of a parallel though, between Newton soft, Jason and 10 Loman, Jason. So I wonder if that's part of the popularity. Right. So can you give us like a just very quick overview of maybe what the library does? Like your bio says, it allows us to treat JSON as a first class data type. What does that mean? It meant for me that when I first tried to use JSON, I was a bit motivated by Python, that in Python, basically everything is a dictionary. And you just throw in whatever you need. And I wanted to have a type where it's using the variable, I don't need to worry whether it should be an array or it should be an object or a number, etc. So this is what I mean, like a first class data type.
Starting point is 00:16:53 There are some libraries out there where it seems that it's always up to the developer to decide for the type. And I wanted to have JSON being the type. And this is what I have the feeling is the core contribution there that you don't need to worry about this. And then of course, there's a parser to get data in and the serializer to get data out. And then it grew. And from the design perspective,
Starting point is 00:17:21 it maybe looked like an anti-pattern, like standard string where, I don't know, 50 API methods that nobody wants to memorize or use. But at the same time, I try to have it useful and solve all the JSON problems a C++ programmer may have without worrying too much about APIs. So I try to make it look like, I think I have it in a tagline, like what would JSON look like if it would be part of modern C++? That's pretty cool.
Starting point is 00:17:54 That was basically the idea. I'm not sure whether it's the answer, but at least when I look for API names, I always try to look at the STL and ask like, how would the STL call this? How would the STL make it look like that people don't stumble over it all the time? Right. So basically you have JSON, which is a single type.
Starting point is 00:18:14 And then I guess there's lots of type erasure going on under the hood and all that stuff. Yes. It's less sexy as it sounds. And today with a variant, you're basically done. But in C++ 11, we didn't have variants. So we had to do this by hand. And still, the magic is not there. The magic is that you basically never need to worry about it.
Starting point is 00:18:36 And I try to hide it away from the developers. But of course, C++ developers look into it. And then they see it. At debug time i can't hide it it's you see the std map or the std vector and yeah you have to so if you were starting it today from scratch would you use std variant or do you think it's still worth having a separate data type i'm not sure because i never i i would do so much differently that I wouldn't worry too much about this I think I would need to make it even more configurable as it is right now so maybe not
Starting point is 00:19:14 using std variant because it could block some design decisions in the future but yeah if I if there was very std variant when I started, I think I would have used it. Right. And std variant is not, I don't like it too much. The API is still a bit clunky at times. So it's not the nicest C++ to copy and use it. Yeah, there's like weird corners, like valueless by construction or what is it like?
Starting point is 00:19:46 Valueless by exception. Oh, valueless by exception or what what is it like a value just by by exception oh valueless by exception that was it of course like when you when you uh throw from a throw from and placing a new one in but you can't get the old one back because that would require a heap allocation and you don't want that so you left with basically nothing i remember that was that was a very, very difficult thing to sort out on the committee. We fought about this very bitterly, I think, in the lead-up to CSR 17. Yeah, because that wasn't in the original Boost version.
Starting point is 00:20:13 Yeah, but the original Boost version was allocating, so to not have that, and that was kind of a... So I guess those are the questions you kind of ask yourself as well a lot, like with all of these trade-offs, right? This thing, it could like be faster but then if this other thing happens you have to allocate how do you make these design decisions like because you have so many different use cases for this kind of stuff right so how do you optimize in a way that to make everybody happy oh i i gave up on that no i i basically a lot of
Starting point is 00:20:43 these design decisions have been made before the thing got popular. So a lot of things were there in the 1.0 and the 2.0 already. A lot of decisions were not too bad because the breaking changes were not fixing the API. It was more fixing some details, but it seems that either people who are very, very unhappy with it are not using it or they don't complain too much. That doesn't mean that I make everybody happy, but people are usually more unhappy about performance,
Starting point is 00:21:18 but not so much about the API. And yeah, API is difficult. So I would do a lot more. The moment I went to the 1.0, I should have written down what it means to have a stable API. And now I'm hesitant to even change strings in the exceptions I throw
Starting point is 00:21:38 because I know that there are people catching the exception and looking at the strings. So changing this would already be a breaking change for some people. And that constrains a lot. And then a lot of issues I have to close and say, listen, I'm not going to make a breaking change to fix this. So we're a bit in a corner here and I'm not sure how to get out of this right now. Maybe having the 4.0, but then I would need to, I don't know, lock myself into a cave
Starting point is 00:22:08 for two or three years to look at every email I ever got, every complaint, and then I come back and say, this is the 4.0. But I imagine it would take a week and then someone comes in,
Starting point is 00:22:20 oh, listen, you forgot about this and I have to do the same again. You call that Jason for contemporary C++. Right. I think that's what you described as basically Hiram's law, right? It doesn't matter. I don't think it even matters what you document as this is the stable API because as soon as your library has any kind of observable behavior,
Starting point is 00:22:40 somebody will depend on it, especially with this huge amount of users that you have. Yes, I'm not... You've been using randomizing those messages. I'm not complaining. It's also for me, I wish I would be able to have this documentation to be able to have quicker,
Starting point is 00:22:57 to deal more quickly with issues coming up, because a lot of people are asking questions and it would be easier to point them at documentation and say, listen, here's written down written down but unfortunately that part is not documented so it's still a source of confusion so you've hinted a couple of times at the origins of the library but um i mean how how was it born if you like why did you write it in the first place because it was not the first jason i – so at university, we wrote some verification tools, and these tools have to be as quick as possible. So basically, it's a glorified malloc.
Starting point is 00:23:33 So you ask for as much memory as you can get to store state spaces. And we needed some kind of check whether the tool is still running. So usually, you start started at some university cluster and let it run overnight. And we just had some loop that every 10,000 iterations just sends a TCP package or UDP package. And we wanted to put some JSON on site there. So before it was hard coded,
Starting point is 00:24:01 but then you start escaping strings. And at some point you say, okay, listen, we need to make this properly. And then we had just some beginning of this type to say, OK, well, I have this mapping, this STD map, or I have this string, make a JSON out of it. And then a colleague started to write a parser for this and say, listen, we can use this for configuration. And then it grew out of that. So we never looked at third parties, but we just wanted to get the job done with as little code as possible. And yeah, out of that, it started.
Starting point is 00:24:36 And then I wanted to learn C++11. So I've looked for an excuse to have a look at all these shiny new features that we have. And this brace initialization was really sexy because then you could basically write JSON code as a literal. You could just say, use it as an array or initialize an object by a pair of string and some value. Unfortunately, it seems that there's a different behavior from Clang and GCC, which basically breaks this right now
Starting point is 00:25:11 because they disagree on how to interpret this. So that's a problem now, but back in the day, that was really cool. And then I just put it on GitHub because I left university at some point and that was part of the code where I had the feeling this could be useful for other people. And it was. That's why this part of the thing made it to GitHub.
Starting point is 00:25:35 And then I kept working on it because this was a bit like my happy place. So if you're getting paid to write software, then usually in any company you have any constraints. So nobody says documentation must be perfect. Nobody says test coverage must be 100% or something. It would be nice if it were like this, but you have constraints. But that project was my pet project. It was about what if I wanted to have 100% test coverage? What if I wanted to have 100 test coverage what if i wanted
Starting point is 00:26:05 to have documentation that is nice and there it grew and uh yeah i i always did it on the side to have some kind of code base without these constraints where i can say this is the could be the perfect project and uh yeah it grew and now people are using it that's really cool it's actually i'm pretty sure, the most popular C++ JSON library in the world. I'm certainly judging by GitHub stars. I don't know if there's any other metric, but it is the one JSON library
Starting point is 00:26:34 that I have encountered almost everywhere when people are writing code in C++. They were using it. So it's massively successful. Did you have any idea that it will turn out that way and do you have any idea why why it became so successful so of course i had no idea that it could go like this so um i i when i started i was happy about like a hundred stars and then a thousand stars and now it's 40 000 stars and i i it's it's it's it's a weird metric, but I'm a bit proud to see that those libraries with a similar amount of stars are written by companies.
Starting point is 00:27:11 So this is what I like. At the same time, it's unfortunately nothing where you can go to a shop and say, I'm going to pay by GitHub stars. So I'm taking this car and here are my stars. So that's not working. It was my first GitHub project, so I didn't expect anything. But I think a reason why it grew was at least what I think is I cared a lot. I really wanted to make it nice. And I really would, as I said, this is like my happy place to say, I don't have any excuses here not to make it nice.
Starting point is 00:27:44 Apparently I had way too much free time but i it was always like this is the the source code i want to get back and feel good about it's not yeah suffering all the constraints that you have at work where it just works or it has to be shipped there's there was never a deadline i could postpone a release as as often as i could and this is what i try to continue working and if people came back and and say i i don't like it because and if it's something that i could fix i try to fix it so yeah i i'm not sure whether this is a as always the ticket to success but it could be if you're if you're willing to invest a lot of time for it. Yeah, I can definitely relate to that.
Starting point is 00:28:26 I had a similar experience with Catch, especially in the early days. It's like, well, actually, I can do what I like here. I can go deep on this thing that nobody really cares about except me. Make sure everything is nice and consistent, even though that takes a lot of extra time. And I think it does pay off in the end. I think people do notice that sort of care and attention at least you learn i mean this is what i i learned that it's possible to get there and it takes a lot of time and i now uh feel better when i have excuses about it when i
Starting point is 00:28:56 say i we're not going to go to 100 here because i mean it's it's not sustainable, but at least I tried and I knew it's possible. And I sometimes wish that some other code that I use would be, I don't know, better documented. Then I don't need to find out how it's working. So, yeah, always room for improvement. But it's good to have some examples. And, yeah, I love Catch. I started using it. And a huge test suite where we use Catch. We're now using DocTest, which is pretty similar, but a bit faster now.
Starting point is 00:29:34 And then I heard a new version of Catch. We never checked that because at some point I didn't have the time to try out everything, unfortunately. All right. So it seems that you both have experience with maintaining a massively popular library. So I guess it's a question for both of you. But how much time does it actually take? Because it sounds, Nils, like it's actually not part of your job at all. Like you're kind of doing it in your free time.
Starting point is 00:30:01 Yes. So how much free time does that really eat up? Right now, not so much it's uh it used to be a lot in the past now i have small kids which takes a lot of time and um it's also there is time where programming is really fun but there's also time where i mean now it's getting warmer outside where it's not the time the kind of time you want to spend so it used to be like a few hours every day um because it's just there was so much to do and i'm i'm very easy to be motivated by others so i had some pretty uh substantial contributions by some individuals who really had a merch request open for half a year or even longer, where they
Starting point is 00:30:45 implemented a huge feature and they asked for feedback. And then I felt bad if I couldn't give them feedback quickly. And I had the luxury of working with a few of those at the same time. So I had to really take the role of some kind of a manager or some kind of a different role and then i i felt it can't be me now who say i can't do this so there put a lot of time in that but once that stuff was shipped i i put a step back and say it's okay now i can can leave it at this so um it depends but i i at a long time i spent nearly all my free time and the weekends in the library. Yeah. And to directly answer your question, Timon, how much time does a project like this take?
Starting point is 00:31:32 All of it. All of the time. All of the available time. And it's not sustainable. And I mean, it's not even a security critical library. I mean, you have the XE discussion. There is a lot going on already if it's just passing json so there's a lot of a lot of people who are also not very constructive and this is also something i learned that initially every pull request is like got sent like present and then you
Starting point is 00:31:58 you you you basically you merge it and then you clean up in the sense that okay you didn't write tests but maybe you didn't have the time. But you did this in your free time, so why should I reject it? And this is something I also needed to learn to say, sorry, if the CI is not green and if you didn't add any tests, I'm sorry, I cannot merge this. But yeah, I stumbled into this and now i'm looking at my phone if there's someone i mean now i'm way more relaxed in rejecting merge requests because some people really want to do stuff but not really be helpful and willing to go all the way this is also something i needed to learn that uh yeah my time is also precious that i don't need to accept anything from out there yeah yeah one
Starting point is 00:32:44 related piece of advice that I'd give people working on their own open source projects, enjoy it before it gets popular because once it gets popular, you'll be overwhelmed and it'll just be constant fight just to stay on top of things. And yeah, pull requests are great, but they still take a lot of your time. So I was kind of toying with the idea of, you know,
Starting point is 00:33:06 having an open source library. And like I even started putting together this project where I put like some of the kind of tools, like low latency kind of generic tools that I use in different projects. And I kind of started putting them together in a library. And I was like, okay, maybe it would be fun to grow this a little bit more and implement this thing
Starting point is 00:33:23 and this thing and this thing. And then it might become popular i think right now i'm just gonna not go there for the time no you should no you should i mean the worst thing that can happen is that you have the feeling that why do i need to do this the time. And why isn't there a library out there? So that's always the best motivation. And I mean, putting stuff on GitHub or wherever doesn't, I mean,
Starting point is 00:33:51 nobody's judging you that it's not perfect. It's not integrated in all the package managers or whatever. So I would always, I always start starting is always the best thing. And some stuff is always helpful to other people. So, yeah. It just sounded so bad. So it doesn't mean nobody has to put all their free time into this.
Starting point is 00:34:15 I mean, if you're a software engineer, then this could be your hobby. Other people have a boat and do sailing or have anything else. So it depends what people like right so so when you do uh work on your library do you feel like it's mostly kind of bug fixing and pr so do you actually keep adding new features yourself um because it's kind of jason it feels like it's kind of a closed standard there's like a limited amount of features but maybe there isn't maybe there's like new stuff and like is there anything like that that you can talk about no right right now i'm i'm chasing new versions of clang tidy gcc clang whatever if there's a new version then i
Starting point is 00:34:58 have like 50 new warnings and i need to fix them somehow. I try not to just suppress anything. I really try to look at this, but right now there's – the CI is red because we have a new version of Clang Tidy. I haven't fixed all the Clang Tidy warnings. I right now don't have as much time, so maybe a few hours per week, and that's why this is currently blocking things. From the JSON side. I have the feeling I'm done. And if I would add stuff, then it would be making some APIs more configurable.
Starting point is 00:35:39 People have a lot of, are very opinionated about how JSON should be pretty printed. And most people would like to have like, it should be Turing complete, I guess, to put a configuration language in there to say like, okay, it's an array. If it's two numbers, then there should be a new line. But if it's four numbers, everybody has their examples. Sometimes people put matrices in JSON and they want to see a square and it should be nicely formatted and stuff like this. And this would close, I think, 50 open issues if there would be a proper configuration for this. But I'm very hesitant because I can't make everybody happy here. So we're going to have a little configuration language
Starting point is 00:36:16 embedded into the library that's going to be interpreted that you can use to like... I have the feeling the parameter to describe how it should be serialized should again be a JSON object. I was going to say, yeah. So then it's not type safe anymore. And then I can, in the future, just add random additional keywords and have this open. But then the performance fanatics come around and say serialization is 4% slower and you should not do it. No, seriously
Starting point is 00:36:48 I'm currently feeling comfortable to just let it go. I want to see the CI being green and I want to make it a place where other people can come with their ideas and then I can help them put it in. But right now it's not that I have a big
Starting point is 00:37:04 feature out there where I just wait until I can finally merge it. So I don't have anything planned. If the CI is green, then I guess it's time for release again because we've fixed so many smaller issues, but nothing spectacular. Right. Since we mentioned Catch recently, let's bring you around to testing.
Starting point is 00:37:24 How do you actually test your your library i test a lot so um one thing i learned if you write a library that you have no idea where people are using it and since it's header only i i have to care about their compilers and right now we have a ci with i have had to look it up, 59 compilers, different version. So 53 versions, three operating systems, three architectures, a lot of things where I just try to make sure that I don't miss anything. And if people come around and say it's not working, then I can have an easy time and say, listen, it's working in the CI. So I'm not going to debug your compiler. Maybe you did something wrong. So I have a lot of unit tests. I also looked it up. I have 112 million unit tests, so individual checks, including a whole test suite
Starting point is 00:38:19 of 8 million strings to make sure that every Unicode string is tested. Also, again, to make sure that if anyone comes around with, I don't know, sending me screenshots in Chinese that I cannot read, I can say, okay, if you start it as UTF-8, then you must have done something wrong because I'm pretty sure I implemented it correctly. I have 100% LIDAR coverage. That's why it's not so many tests. And I try to test with all the warnings enabled. So in Clang, it's W everything. And I also looked it up. And I also have a Python project to create all the warning strings for GCC. And right now, we have 277 GCC warning flags. Again, to make sure that this is not blowing up
Starting point is 00:39:07 people who really care about compiler warnings. I don't want to be the one who make their code unhappy. We learned a lot by OSS Fuzz. So it's part of Google's OSS Fuzz. And that's really helpful because I have a lot of parsers, not just
Starting point is 00:39:23 JSON, but also binary formats like UBJSON or CBO or a message pack. And there have been bugs, of course, always are. And it's now nice to see it's running 24-7. No more bug issues are coming in. And that helps me sleep at night that at least the obvious things are gone now so i try to make testing really an important thing again just to make sure that it can be really used anywhere and i can also recommend it to people at work where that i work with that i know that you will have issues but the issues will not nothing that you see in your build system that
Starting point is 00:40:02 your compiler complains about stuff. So you're testing all your stuff on CI. You said you support lots of compilers. Is it CSS 11? Is that the requirement? Yes. Yes. But we also test with all the other versions because we have a lot of implicit conversions. So you can serialize STD file system or std variants or whatever so things that came
Starting point is 00:40:28 to the language after c++ 11 but they're still shipped and a lot of macro magic in there so um i i would expect every new version breaks part of the code because we're just naive and don't know how the new compilers look like. And I guess you don't have third-party dependencies or anything like that. And I guess it's a thing where, could I run your JSON library on, I don't know, my toaster or something? Is that embedded support,
Starting point is 00:41:02 or is it all allocations everywhere and things like that? It's as many allocations as you would expect if you use std vector or std map. You can put your own allocator in there. People have been using it. So if you're toast, the biggest problem is, do you find a compiler with a proper STL for your toaster? So there are a lot of compilers out there that having a proper STL is already a challenge. But when it comes to embedded systems, there's one thing I'm very proud of. There has been a mission with the Moon Lander recently, the Peregrine 1 mission,
Starting point is 00:41:42 and they used my JSON library as configuration management. And unfortunately, they didn't land on the moon because they had an issue with the rocket. But at least my library was in space, orbited the moon once, and then burned in the Earth's atmosphere. But at least some people looked at libraries and thought, well, we want to bring it to space. And at least C++ is now out there. The embedded systems are big enough that you don't need to worry about this.
Starting point is 00:42:11 That is so cool. And if people tell me, do you worry about allocations? You can worry to death about this, but I can always say it was good enough to go to space. That is really cool. And of course, we should using the the standard toaster library yes uh the library is not big enough yet so it would be nice to have this in no seriously i work with uh at my company we're doing embedded uh software for automotive for the automotive industry and um we use proper compilers, normal compilers.
Starting point is 00:42:47 We do have some language constraints about what to use and what not to use. But so far, using libraries that solve problems, that's not an issue anymore. Writing your own JSON library to avoid a few allocations is usually not worth it. So I know there are people with very hard constraints, but I think the word embedded is now a bit burned by this powerful embedded systems we have
Starting point is 00:43:15 out there. So the different compilers you're using, are you using some of the non-mainstream ones? Not one of the big three? I use GCC, Clang, Xcode, ICC, NVCC, Visual Studio, and some forms of MinGW. These are the ones. And I have some tests using CUDA
Starting point is 00:43:35 because apparently there are some issues for that. Usually it's limited by what I can get my hands on as an open source developer. So that is something I really hate to see that it's very difficult to have compilers work for a long time. So you really need to have your Docker image and that Docker image disappears or something changes. So it's very difficult to go back in time and really use the
Starting point is 00:44:06 old compilers and also the new ones and all this i uh that's why it's right now if if anything breaks i don't have the time to fix all of it but this is like my collection of small compilers and compiler versions right so i mean we talked about this a little bit at the beginning of the episode but obviously it's been many years of you working on this library is there anything that you would say you would do differently if you had to do it again is there any any major lessons uh learned or any like particular super hard problem which you had to solve where you're like oh i wish i hadn't done this that you can like you know say to people other people who are you know considering embarking on library projects like that so the hardest issue in
Starting point is 00:44:52 retrospective is finding a good and stable api there's only so much the library is doing but there are so many different ways how to do it. I think I have 15 different constructors, like how you can put stuff into the library. And I would like to remove a lot of them because a lot of times a pair of iterators would have been sufficient, but instead I have overloads for different types. And this decision is like forever. I would never make a new release
Starting point is 00:45:26 just to get rid of some things I did. And also C++ is still a horrible language to have a lot of parameters. So it would be nice to have name parameters and name parameters with default arguments that an API is not immediately ugly just because you want to have four or five parameters. Hence the problem with serialization.
Starting point is 00:45:51 There are so many different options. And if I now add a new parameter, it's a problem. If I switch to have a struct that collects all the parameters, then I have a second version of this. And if I knew now what I knew, if I knew back then what I know now, I would have made a smaller API that still covers all the use cases.
Starting point is 00:46:15 Yep, that is one of the things. And maybe back in the day, I should have thought about this stable API and maybe rejecting a few features and put them into helper libraries and not in the main header because now everything is part of the namespace and part of the same header.
Starting point is 00:46:35 And that makes compilation pretty slow and would be easier if I would have split it. But all these issues would be solvable if I would just say listen here's a breaking version uh you have to adjust your code and then it's fine yeah if there's any consolation i'd say it's almost exactly the same that you just said of catch so i'm sounding very familiar i'm i'm not blaming the language it's just it is how it is but at the same time if i would still work with so much time on my hands,
Starting point is 00:47:08 then these issues would be solvable. But right now I think it's good enough to just let it go and see. Yeah. But I now know that API design is a pretty hard topic. Yeah. And I always, this is something I like to see in my company. If people talk about APIs and they really want to look for solutions.
Starting point is 00:47:33 And I really like if a lot of people talk together and it's not just one person making a proposal that suddenly is the 1.0 and a lot of people have to suffer their bad design decisions, but rather it's something where people should immediately learn this is something set in stone that you will not be able to fix anytime soon. So we're so used to writing software that everything can be changed all the time. And this is something I learned where it should be good the first time you try. Something I've noticed over the last couple of years in particular, we seem to be shifting to a lot more talks at conferences about API design and some of the things that we thought, oh, you know, everybody knows that. But actually it turns out, first of all, that everybody does know it,
Starting point is 00:48:18 but also that what everybody does know is different and we don't necessarily have the agreement on what the best way to do things is especially in modern c++ where it's a constant moving target so it's good that we are getting the stuff more out in the open but it remains a very hard topic yeah i mean we um we have a track about this actually at cppcon again this year software design track and it's a hard problem i think as a kind of more junior developer i probably produced quite a few of those bad apis that you were talking about and it took me i think quite some time to like figure out that when i'm writing a library even if it's like an internal one at a company that like i shouldn't think about how do i package up like the functionality of the library in a way that looks good to me as a library author but i i should think from the other side okay the user wants to use this to achieve this concrete
Starting point is 00:49:09 task or this concrete task like what code would they have to write on their end like to achieve that and what would that code look like and is that easy and obvious code to write or does that code look horrible and i think that's took me quite a few years to like even just absorb that mindset. And without that, you're just not going to have a good API design ever. I found a nice trick about this when ChatGPT came up and people were praising it, although the developers will be unemployed soon.
Starting point is 00:49:40 I asked it about some, I just pasted issues or support requests for my library in there. And I always got an answer, of course. But most of the time, the code that it produced was wrong. But sometimes it just came up with an API, which was not existing. But if I would have implemented it, I probably would have called the same way. So it was very good. So if the feature would be there, how would have implemented it, I probably would have called the same way. So it was very good.
Starting point is 00:50:06 So if the feature would be there, how would I call it? And that was eye-opening to me that these tools could be to really use the hallucinations to give you an idea how it could look like. And yeah, I liked it a lot. And I tried this at work sometimes to really say like, this is currently my API and I want to do this and that. How can I do it? And you always get an an answer and sometimes it's pretty good right so instead of learning the hard way how to design good apis you should all just trust chat gpt to do it for us no no no no but you you know what i mean yeah yeah i mean I was talking right yeah check GPT driven development
Starting point is 00:50:46 yeah I mean GitHub Copilot is also helping a lot by just sometimes you just do tap tap tap and then you have something where you
Starting point is 00:50:54 say well why not it's good enough for a first try and sometimes the it's it's not too bad I'm I'm quite often amazed
Starting point is 00:51:03 how how an AI can look into my head and say, yeah, this is really what I wanted to do right now. Let's see. Right. So we talked about how if you put an API out there, it's pretty much set in stone.
Starting point is 00:51:18 You can't change it because you would break other people's code. We have that problem, I think, maybe a even in a more extreme way like with the c++ standard library right so once something is there like it takes an extraordinary amount of effort to change anything and it's like happens only very very rarely that said do you think jason would be like a good candidate for something that should does that belong in a css standard library would you see something like your library uh or something else like that like being added to namespace one day or do you think that just doesn't belong there because like jason is one of those things that are really common right if you write any kind of app eventually you will you will need something like that right and so if it was just there in your compiler wouldn't that be nice but then other people are saying well but this is like high level stuff it doesn't really be like
Starting point is 00:52:09 it's i'm curious about your take on this i was approached several times by different people about this so there exists a repository in my username called stit json where some people started writing a proposal but i have the feeling that the work it would take is does not justify the potential outcome package managers are getting so much better so i think if you really need any kind of json library there are means to have it in your project more quickly. And I already see how people, there are so many different opinions about what comes into a JSON library that I think you can only fail by. If you are too conservative
Starting point is 00:52:56 and have only very few items in the list, then you still need a lot of utils around it. And if you standardize everything, people will hate you from the start by having another anti-pattern in there. And I'm not sure whether you should put in a parser in there and care about Unicode. And I think it opens up so many other topics
Starting point is 00:53:20 where it's not just JSON, it's the stuff around it. And then again, people are so, C++ people like to talk about performance so much and then you would have so many different opinions like what should you do? What should you optimize for? I mean, should you optimize for the fastest parser in the world, but then you have an immutable structure
Starting point is 00:53:40 that it's hard to query? Or should you have something that you can immediately manipulate and serialize again? And I think there will not be the one-size-fits-all solution. So if people want to do it, I'm all happy, but I'm not the one who's pushing this at all. And I'm not blocking it. It's just, if people want to do this, why not go ahead and have fun? When this sort of discussion comes up, we usually fall back to saying, well, maybe we can just come up with some vocabulary types
Starting point is 00:54:12 that you can use in third-party libraries. And I think in this case, there's a very clear one, which would be a language-level variant. We talked before, you know, std variant is not a great API. It's got all these issues. It's a bit ugly to use. There's been talk over the years of a language level variant, and maybe we'll get it, you know, C++ 32 or 35 or something.
Starting point is 00:54:31 But do you think that would help? If I look at other languages like Python, et cetera, where you have the network built in, and then you have still a lot of libraries that makes the network easier to approach and have different libraries to implement the same interface for for the json stuff then i'm not sure where you should start where i should stop because why are people using json most of the time because they pull stuff from the internet i have so many so many questions about how to link curl with my library.
Starting point is 00:55:06 And then you have this, okay, you're in the C world. You have some char pointers, and then you suddenly want to parse C++ stuff out of this. So I'm not sure whether it makes... I think in the language stack, Jason, it's like here in the very top, and there's still so much stuff missing in the standard. Yeah, I think we had something a little bit similar happened when we were discussing whether to standardize 3D, like 2D graphics.
Starting point is 00:55:35 And then people said, yeah, that's kind of too high level. And like that got shut down. But then we started coming back with like lower level utilities. Like let's do linear algebra. Like let's do like, you know, geometry, let's do colors, you know, just kind of a little bit piecemeal kind of thing. It feels like with JSON, well, well, I guess you kind of want to pass JSON and then serialize,
Starting point is 00:55:59 deserialize it and kind of map it to objects. Right. So that's kind of the one thing you want to do. But yeah, I guess, I guess like there are package managers that lets you get your library very quickly so i guess i guess i guess that's fine there are actually a few other uh json libraries that enjoy i think some popularity i came across rapid json and simd json at least i don't know how many others there are they're not JSON we discovered just recently, I think, after a SIMD episode. Right, right. Yes, yes, yes, yes. I haven't personally used them.
Starting point is 00:56:32 Do you know, like, if it's a case of, like, depending on what you want to do, you're going to use a different one? Or is yours kind of the just default recommendation? Just use Niels' library and you'll be good. It depends on what you want to do so i i do have a project where we convert uh wiki data and you download 150 gigabytes of a json file and then of course i use simd json because it's just so fast it's it's amazing but it's more or less just reading and immediately writing into a database. But if you want to use JSON, like most people do, to just serialize some objects at configuration
Starting point is 00:57:12 time or reading some objects and performance is nothing you need to worry about, then I think my library is at a good state where you don't need to worry. Then it's just the lines of code you write is just you write two or three lines of code and the job is done and usually developers want to have their job done and not worry too much about it and i have the feeling that my library can be helpful there but i i know how much faster other libraries are and i gave up in into apologizing for that it's just if you need performance go to simdgs and then have fun yeah right i mean that was kind of my experience with your library it's it's really easy to use it does the job and i have not personally come across like i haven't personally worked on a project where like that
Starting point is 00:57:54 was the performance bottleneck if if i was doing that then you know maybe things would be different but i just not something i've come across yet. So yeah, your library is great. Thank you so much. Thank you. No, no, it's okay. Thanks. So what do you do when you're not maintaining your library? So you said like, you're kind of winding this down a little bit. You said that you're now writing games for cars and other things.
Starting point is 00:58:19 Is that also C++? No, I'm leading a team of a few developers that currently our our team job is to write in-car games for mercedes-benz working at a mercedes subsidiary and the language of choice or the framework of choice is is unity so everything is c-sharp but there's a lot of infrastructure around it where i personally write code. So we have some database layer that is a SQLite database that is wrapped in C++. So this is part of my day job and a lot of backend interfaces to receive data and store data, doing high score stuff. And that is currently a lot of Python. So I'm personally more on that side and i would love to do more c++ but right now that's
Starting point is 00:59:06 not possible but if you want to write games then it would be ridiculous not to use one of these enormous frameworks where it's very easy to get ridiculous amounts of of gameplay objects in such a short time and it's yeah that that's why I'm on the sideline looking at the team, what they try to accomplish or what they do accomplish. And I'm doing my little part of C++ and I feel like the old guy at the sideline telling back in the days, I also used to write code.
Starting point is 00:59:40 So I would like to do more C++ code, but it's not working right now. Yeah. Right. But you are keeping an eye on the latest developments So I would like to do more C++ code, but it's not working right now. Right. But you are keeping an eye on the latest developments in the world of C++? I try to, but I have the feeling that if I look away and look back at the language, it evolved so quickly. Right. And I'm switching a lot between Python and recently a bit of Swift. And it makes me question a lot of things in the, in the, in the language.
Starting point is 01:00:06 I like Apple's approach to just telling you like, by the way, this is all broken now, press here to update your code and then you, you don't have backwards compatibility, compatibility. It just helps you fix it. I like this clang tidy approach and I would love, I would love to have more like this that I can, I don't need to worry about the new standard.
Starting point is 01:00:26 I have a tool that just tells me, listen, this and this and this is good now. We modernized all your code base, and that would be nice if everything that is newly standardized had some kind of tool support to help people like me to catch up. But the language is growing so much. We had back a few years ago, we had some kind of mini session where a few developers were looking at the STL
Starting point is 01:00:52 and just like the library, not the library, like the API of the week, something like this, like nothing spectacular, but just like, did you know there was that one function that is doing that one thing that most people never heard about because nobody's looking through all the headers at all the functions? And that was always so embarrassing that you had all this. So many people wrote.
Starting point is 01:01:15 It's something like, did you know that you can find the minimum of a sequence of number by having this one API call? And like, oh, somewhere in my code base, I have a function that is doing this. I can replace this by std min or max or something like this. And it's going like getting crazy. So I, yeah, sometimes I would like to see the language to drop a bit of old deprecated things, but I know that that's not the design choice of C++.
Starting point is 01:01:44 Yeah. I mean, people have tried right there was vittorio robio who had the proposal with the epox or you know let's break a few things uh but then it basically failed because people were like okay well but if you have a i don't know a part of your program compiled with like this version and a part of your program compiled with this other version you have a shared header you have like templates in there. Like, what does that happen?
Starting point is 01:02:07 How does that work? Like what happens then? And then nobody had a solution. So we were like, okay, well that doesn't work then. And just, you know, nobody came with a different proposal how to do it. Like now we have Herb with his like CPP2, but that's a bit different, right?
Starting point is 01:02:22 That's actually like a kind of a like a different language on top with a transpiler so it's not quite that either i don't know i i would love to see something like this but i i don't really know how to do it maybe nobody does maybe somebody just has to figure it out yeah if it would be easy solution we already would know how it looks like and i think actually i remember i had a conversation with one automotive person who said well they were doing something similar like maybe not games but like fancy ui like in the car and then somebody else was doing like a highly like safety critical part of the car like i don't know the airbags or whatever i don't know and then they had like this
Starting point is 01:03:01 one header that like both of them shared and. And you cannot change that header because it's certified. And it's going to cost you hundreds of thousands of dollars to recertify it if you change anything. So we have those people coming to the committee and telling us, Don't touch anything. Don't touch anything. We touched a few things. I think we threw out std bind first and std bind second. And like,
Starting point is 01:03:26 now we're throwing out still stream. And every time this happens, there's somebody saying you, you can't do it. Like, Oh my God, what are you doing? Like,
Starting point is 01:03:34 so it's, it's, it's a delicate dance, you know? And then you have all the people who really want like to get rid of all the old stuff and, and like do something better and safer and more modern. And like, yeah, what do you do yeah it's tricky so maybe it's better to have your own
Starting point is 01:03:50 library where you know you can break things if you think you need to or maybe you can't but at least you know you make the decision yourself i don't want to to uh to how to say to have the kind of responsibility that the committee has. Because I mean, I only have a few people who get upset if I change anything. But you can upset so many more people. You can upset whole industries. And that's so much power.
Starting point is 01:04:21 How can you sleep at night? I don't know. Sometimes I don't. So with that in mind, is there anything else in the world of C++ that you do find particularly interesting or exciting? I like the performance stuff. I always remember why people choose C++,
Starting point is 01:04:46 especially when you come from Python and you write your stuff in pseudocode that just happens to run. And then sometimes you have the feeling it's so slow and then you have to write like 50 times the lines of code in C++. And then you suddenly have the same problem fixed with 0% CPU and it's just done.
Starting point is 01:05:07 I recently changed something in the backend and it was like, did it really do anything? Because it was like, done. It's the Python code that seconds to do that. And this is what I love the language for this. You compile it, you run it, and it just does what you want and zero overhead that you don't want to have.
Starting point is 01:05:27 I really enjoy that. But every December when it's Advent of Code, I would never use C++ to solve these problems because it's just, but I don't like having a solution in my head. And then it feels like, okay, now I just need to write this 50 lines of code where I have to feeling some parts of it are so cumbersome that I would love to have someone take it out of my hands. So if it's not the language that can evolve for lazy people like me, then maybe the code completion can. Right. Well, this episode was obviously not written in C++ because we have run over time. So we're going to have to wrap up. So is there anything else that you want to tell us
Starting point is 01:06:28 before we let you go, like where people can find you? I used to be on Twitter, but that's not an option right now. If you want to find me, you can Google my name and you'll find how to contact me. And if you have any cool C++ jobs in Berlin
Starting point is 01:06:45 and can convince me that I should go back to writing C++ full-time, happy to hear about this. Until then, I'm happy where I am. Yeah, so much about that. And I would like to hear, if you're using my JSON library, I'm always happy to hear what you're using it for
Starting point is 01:07:00 because that's also a lot of motivation to see what kind of problems you have other people solve. Great. That's a great call to action. So thank you very much for coming on the show today and telling us all about your Jason library and the whole history of it. That was really interesting.
Starting point is 01:07:17 So yeah, thank you very much. Thank you. Thanks so much for listening in as we chat about C++. We'd love to hear what you think of the podcast. Please let us know if we're discussing the stuff you're interested in. Or if you have a suggestion for a guest or topic, we'd love to hear about that too. You can email all your thoughts to feedback at cppcast.com. We'd also appreciate it if you can follow CppCast on Twitter or Mastodon.
Starting point is 01:07:41 You can also follow me and Phil individually on Twitter or Mastodon. All those links, as well as the show notes, can be found on the podcast website at cppcast.com. The theme music for this episode was provided by podcastthemes.com.

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