CppCast - Macchina.io

Episode Date: April 7, 2016

Rob and Jason are joined by Günter Obiltschnig to discuss the macchina.io library for IoT C++ development. Günter is the founder of the POCO C++ Libraries and macchina.io open source project...s. He has been programming computers since age 12. In his career he has programmed everything from 8-bit home computers (C64, MSX) to IBM big iron systems (COBOL and JCL, VM/CMS and CICS), various Unix systems, OpenVMS, Windows NT in its various incarnations, the Mac (classic Mac OS and OS X), to embedded devices and iPhone/iPad. He has a diploma (MSc. equivalent) in Computer Science from the University of Linz, Austria. His current main interests are embedded systems, cross-platform C++ development, JavaScript and, foremost, the Internet of Things. When not working, he spends time with his family or enjoys one of his hobbies — sailing, running, swimming, skiing, listening to or making music, and reading. News C++Now less than 20 spots left C/C++ extension for Visual Studio Code Awesome Modern C++ C++ Committee to shift focus on important issues CppCon 2016 Call for Submissions Günter Obiltschnig @obiltschnig Günter Obiltschnig Links macchina.io Mastering the IoT with C++ and JavaScript - Meeting C++ 2015

Transcript
Discussion (0)
Starting point is 00:00:00 This episode of CppCast is sponsored by Undo Software. Debugging C++ is hard, which is why Undo Software's technology has proven to reduce debugging time by up to two-thirds. Memory corruptions, resource leaks, race conditions, and logic errors can now be fixed quickly and easily. So visit undo-software.com to find out how its next-generation debugging technology can help you find and fix your bugs in minutes, not weeks. CppCast is also sponsored by CppCon, the annual week-long face-to-face gathering for the entire C++ community.
Starting point is 00:00:33 Get your ticket now during early bird registration until July 1st. Episode 52 of CppCast with guest Guntur Obolchnyk, recorded April 7th, 2016. In this episode, we talk about C++ conference news and April Fool's pranks. And we talk to Gunter Obolcznyk about Machina.io. Gunter tells us about Internet of Things and embedded development. Welcome to episode 52 of CppCast, the only podcast for C++ developers by C++ developers. I'm your host, Rob Irving,ined by my co-host, Jason Turner. Jason, how are you doing today?
Starting point is 00:01:47 Doing good, Rob. How about you? Doing pretty good. My company got a HoloLens in the mail yesterday. We bought one of the developer kits. Yeah. So I've barely just started playing around with it. I haven't hooked it up to a debugger yet, but it's pretty cool.
Starting point is 00:02:03 Wait, so not only did your company get a hololens they're letting you use it yeah yeah wow i was i've made it into the first wave of developers to uh to get one so that was pretty nice well that's cool yeah so not really sure what we're going to do with it yet but uh it's pretty neat, and I'm sure we'll find some interesting applications for it. So did you get the chance to use one at the last Microsoft Developers Conference you went to? I did get to use it beforehand at an event where they were letting developers try it out and at that time i played a video game that was using the hololens that involved like shooting lasers at alien robots so now i can do a little bit more with it than uh than just play games oh well not that there's anything wrong with playing virtual reality games
Starting point is 00:02:58 well at the top of every episode we like to read a piece of feedback. This week, I got an email from Avenish. He writes, hello, CBPCast host. Thank you for the wonderful podcast. I really enjoy it. I hope the frequency of the episodes will go up. That's how much I like to listen to them. I also enjoy all the guest interviews you do. The one with Andre Alexandrescu is my all-time favorite.
Starting point is 00:03:22 And he also has a question. What is the music you play at the start of every episode he's been listening to it for every episode for the past few months and it's stuck in his head and shazam hasn't been helpful in searching for it uh i think that came from a website called freepodcastthemes.com it's it's not a real song. It's just a jingle that a guy puts together for a podcast host to use as intros. There's several on his website, and you can commission him to make one for you if you want. So there's no full song for it. And I'm glad you like the show, Avnish,
Starting point is 00:04:01 but I think one week is the most we're going to be doing anytime soon. I can't picture us being able to pump out more than one of these a week, right, Jason? I agree. But if you want to make sure that we keep doing one a week, keep sending us people who want to be on the show. Yeah, we really love getting user or listener help with finding guests. It's sometimes hard for us to just think of new people to interview. So always keep the guest suggestions coming in. We really appreciate it. And we'd love to hear your thoughts about the show. You can always reach out to us on Facebook,
Starting point is 00:04:34 Twitter, or email us at feedback at cppcast.com. And don't forget to leave us reviews on iTunes. So joining us today is Gunther Olbichnig. He is the founder of the Poco C++ Libraries and Maschine.io open source project. He's been programming computers since age 12. In his career, he has programmed everything from 8-bit home computers to IBM Big Iron systems, various Unix systems, OpenVMS, Windows NT in its various incarnations, and the Mac,
Starting point is 00:05:03 to embedded devices and iPhone and iPad. He has a diploma in computer science from the University of Linz, Austria. His current main interests are embedded systems, cross-platform C++ development, JavaScript, and foremost, the Internet of Things. When not working, he spends time with his family or enjoys one of his hobbies, sailing, running, swimming, skiing, listening to or making music, and reading. Gunther, welcome to the show. Hi, welcome everybody.
Starting point is 00:05:28 Thanks for having me today. It's great to have you. So what was your first computer then, Gunther? Actually, the first computer that I wrote some program on was a Commodore C64, which my dad borrowed from a friend. Borrowed? Yeah. It was around 1984 or 85, somewhere in the time frame.
Starting point is 00:05:58 Okay. Shortly after, I got my first own computer, which was an MSX home computer. Not very well known, but was kind of popular in parts of Austria and especially Japan. And yeah, there I did my first programming steps, first in BASIC, then in C80 assembler and then started with Pascal and then it went on eventually got my first Mac in 91 or 92 or so and then I started C programming and also this kind of precursor to C++
Starting point is 00:06:48 that was supported on ThinkC on the Mac which was basically a light version of C++ and from then on basically I have been a C++ guy ever since. Very cool. Very good.
Starting point is 00:07:04 Yeah. So we have a lot of guy ever since. Very cool. Very good. Yeah. So we have a lot of news articles to get through today. Gunter, feel free to jump in on any of these, and then we'll get to talking to you about Machina.io. This first one is just a quick announcement. The C++ Now conference, which, Jason, you'll be speaking at soon, has less than 20 spots left. I don't know the exact number, but I believe it's less than 20.
Starting point is 00:07:26 You're right, Jason. That's what we know. Yes. Yeah. So if you're interested in going to that conference, which we highly recommend, go to cppnow.org and register for the conference. It's register as soon as you hear this podcast. Yeah.
Starting point is 00:07:41 Because they will be running out of seats soon. Yep. The next one uh microsoft just had its build conference and i'm trying to get someone from the visual c++ team to come on the show soon to talk about all the various announcements that were made for uh c++ developers on microsoft's platform but one of the ones i wanted to bring up today was that they just announced a C++ extension for Visual Studio Code. And Visual Studio Code is their lightweight editor. It's kind of similar to Sublime Text.
Starting point is 00:08:13 And we announced this last year. And I think Jason and I, we both had a Twitter conversation where we were trying it out and seeing if it had any support for C++. And it had, like, very basic syntax highlighting at the time. But now they have a full C++ extension, and they're actually targeting Linux support first before they work on Windows support. Because if you're on Windows, you could use the full Visual Studio editor.
Starting point is 00:08:40 But if you're on Linux, you can now use this to debug C++, and it has better edit and highlight support as well. Yeah, that's pretty crazy. I haven't actually tried it yet myself on Linux. But I partially wonder if it's just because GDB is so much easier to integrate with than I have absolutely no idea how you integrate tools with Visual Studio's debugger. I mean, I think I saw a video where they said
Starting point is 00:09:05 that they are choosing to target Linux and Mac first because of the reason I said that. If you're on Windows, you already have Visual Studio as an option. I'm sure they'll do both for the developers that might not want to use Visual Studio but might want this as an option.
Starting point is 00:09:22 Because of that reason, they were going for Linux first. The next one is a GitHub repository that's just a list of, the title is Awesome Modern C++, and it's just a collection of C++ resources, specifically modern C++ resources. It has several libraries,
Starting point is 00:09:41 links to the conferences, some well-reviewed books, blogs that are good for C++. And I actually put in a pull request to get CppCast added here under the list of websites. But it's just a good resource of good modern C++ stuff. I probably should send them a pull request to also include Poco. When I checked today, I guess it was missing. Oh, yeah.
Starting point is 00:10:13 Yeah, submit a pull request to get Poco in there then. Definitely. Jason, I think Kai's currently here, right? Yes, and I did not submit a pull request for that. Someone else did. Nice. I was pretty pleased with myself there. Very cool.
Starting point is 00:10:30 And this last article now, Jason, did you realize this was an April fool's article when you first read it? Um, well, I actually assumed, I assumed from the title that it was, and I was kind of tired of April fool's stuff. so I didn't read it when I first saw it.
Starting point is 00:10:50 So, you know, when I first picked this article to add to the show notes for the week, I did not read through it fully. I just kind of skimmed it, and I did not realize that it was an April Fool's joke. It's not fully apparent until the second half of the the article when they talk about time travel obviously but uh what the article what the article is basically saying is that there's a new subcommittee of the iso c++ group that's working on the final version of c++ that you, after X many more three-year cycles will eventually be done with C++ and that they're trying to achieve this goal by creating time travel to get there faster. Yeah. Or quantum computing.
Starting point is 00:11:36 Or quantum computing. Yeah. But the idea of a final C++, I guess, didn't sound too ludicrous to me, which is why I maybe didn't realize at the time that it was an April Fool's joke. I mean, eventually, there might be a final version of C++, don't you think? But I think the part about working on important stuff might have some merit. Yeah, yeah. Yeah, the first paragraph in the article is very believable. Right.
Starting point is 00:12:09 Anyway, the last thing we wanted to announce was from the other C++ conference, CppCon 2016 has now opened the call for submissions. So if you have any interest in being a speaker at this year's CppCon, you are now able to submit your paper. And the deadline this year is May 22nd. May 22nd for CppCon speakers. So you have a little over a month. So start on the submissions now.
Starting point is 00:12:37 Are you going to submit something, Rob? I have no idea. I have to think about that. You? How about you, Gunther? Don't know yet maybe i decided the last minute but uh not sure how about you jason yes i will submit something but i'm kind of focused on getting my talks for aspen wrapped up first right i actually have some ideas for stuff time
Starting point is 00:13:01 might something i might submit we'll see okay okay well gunter uh we've been looking for bringing on a guest to talk about internet of things and embedded c++ development for a while now could you maybe start us off by just defining iot and embedded and how they relate to each other uh sure well embedded is kind of a very special topic because embedded can mean so much typically it means some kind of computer that is part of some other device that is by its nature not a computer but how this computing system looks is can be a very small microcontroller. It can also be a full-blown Linux or Windows system. So the term embedded programming or embedded system is very broad-ranging. What a lot of people usually refer to when they're talking about embedded systems
Starting point is 00:14:01 is smaller microcontrollers or real-time systems. We have definitely some resource constraints or other constraints, but as a general term, embedded can mean very much. So for myself, I'm mostly focused on working with embedded Linux machines, which isn't that much different anymore from normal Linux systems programming, except that you have a slower CPU and less memory. But I've also done some microcontroller programming
Starting point is 00:14:47 and so on. So, yeah, it's actually quite a special topic. Okay. Go ahead, Jason. Go ahead. And what about Internet of Things? How does that relate to embedded development?
Starting point is 00:15:05 Internet of Things basically is an even more broad-ranging term. It basically means you have some embedded devices that are in one way or another connected to a network, which again may be a small network like a ZigBee or Bluetooth or something like that, or it might even be a Wi-Fi network that's connected to the Internet. And it's using some kind of standardized protocols. So in IoT, we now have a whole lot of different protocols from very optimized protocols for wireless sensor networks up to the protocols that we know from Internet. HTTP is very popular.
Starting point is 00:15:57 Also specialized protocols like MQTT. And IoT basically means you connect all these little sensor nodes, little devices that are powered by microprocessors or microcontrollers to some other devices, typically so-called IoT gateways, which are usually Linux-powered or Linux-driven devices. And then on the Internet side, on the cloud side, you have some server infrastructure where you collect all the data and use it to obtain new insights, derive some knowledge from all the sensor data that you connected, also to manage all these different devices. So you're mostly focused on devices that can run Linux,
Starting point is 00:16:48 not the smaller sensor devices? Yeah, I'm mostly focused on Linux-based devices. I also play around, of course, with smaller devices. For example, there are a couple of smaller boards that have wireless networks built in. And these are running specialized operating systems like Contiki or Riot or Embed. And most of my actual programming work actually is on Linux-based devices nowadays. So in the current state of the art, how does programming on embedded Linux
Starting point is 00:17:31 different than programming on desktop Linux? For me, it's not really different because I actually do most of my development on my Mac under OS X and then just cross-compile for the target system. most of my development on my Mac under OS X, and then just cross-compile for the target system. So for me, embedded development is not much different. It can get a bit special if you have to do things like remote debugging using GDB server and GDB. But apart from that, it's pretty much nothing special anymore.
Starting point is 00:18:06 Also, you can use nowadays IDEs like Eclipse, which also support embedded Linux pretty nicely, so you can get a really comfortable environment. So like remote debugging, that kind of thing is built into Eclipse? It's built into Eclipse. It's a bit more work, of course, setting everything up, but once everything is set up, you can basically debug like any desktop app.
Starting point is 00:18:38 Except that it's a bit slower and a bit more prone to errors. So what does one of these devices look like, these embedded Linux devices, as far as CPU architecture, amount of memory, that kind of thing, typically? It can range quite widely. I have worked on very small embedded Linux devices
Starting point is 00:19:00 that are basically the size of an Ethernet RJ45 jack. These were a bit limited with just 8 megabytes of RAM and 4 megabytes of flash memory. And you have to do a bit of tricks here to fit everything in. The RAM is usually fine, but 4 megabytes of flash memory is quite small to get a Linux kernel root file system and C++ application in, but it can be done. Nowadays, you have things like Raspberry Pi and similar hardware that can have a four-core CPU with one gigabyte of memory. There are even 64-bit CPUs coming. We already have them on a mobile phone.
Starting point is 00:19:54 They are also coming now to the embedded devices. So actually the gap between desktop systems and embedded systems is shrinking. Okay. But as I said, a lot depends on the actual project and, for example, the cost targets that you have. Although nowadays, with the price of Raspberry Pi around $30, it's getting very cheap to have a very powerful ARM CPU, for example, in your device. Right.
Starting point is 00:20:30 So can you tell us a little bit about Machina.io? Yeah. Basically, I pronounce it Machina.io. It's Italian, kind of. The Italian word for machine or device and basically it's kind of an extension to the poker libraries which i started 11 years ago and it started basically from me playing around with the google v8 engine So basically I wanted to integrate the V8 engine with the Poco libraries, basically exposing some of the Poco features like the web server, web client,
Starting point is 00:21:17 and so on to JavaScript running in the V8 engine. And I was also very interested when I started in the whole IoT space and sensors and this kind of stuff. So basically, I started building some more or less standardized interfaces for different kind of sensors so that it becomes quite easy to get data from different kind of sensors and devices in both C++ and JavaScript. Okay, so if you're an embedded developer and you want to use Machina.io, are you writing in JavaScript or C++ or do you have a choice? You basically have a choice, and the idea behind it is to write the low-level stuff, basically the code
Starting point is 00:22:12 that talks to hardware or implements network protocols in C++, but then do things like application logic in JavaScript. So a lot of these devices that people want to build nowadays have some kind of rule engine. And basically, the idea is to use JavaScript as a very powerful kind of Vue language that allows you to program kind of specialized applications for your device
Starting point is 00:22:50 on a very high level. So you have largely the same API available between the JavaScript and C++ side? Yeah. And how have you accomplished that? All the high-level APIs. The high-level APIs are basically the same. And the way I achieved this is a couple of years ago,
Starting point is 00:23:16 I designed another C++ framework that I've licensed as a commercial product for some years, which is called Remoting, which is basically kind of taking the ideas from.NET Remoting or Java RMI to C++. And what you basically do is you can take a C++ class declaration and annotate it with special comments that basically tell that this class or the method of a certain class should be made available for remote cores.
Starting point is 00:23:51 And also other annotations that allow you to, for example, tag a struct as serializable. And the header files are then parsed by a code generator. And this will generate things like serializers and deserializers, and also all the necessary infrastructure code for implementing remote calls. This has been used quite a lot in the industry, and I have implemented different protocols like a binary protocol, also SOAP and JSON RPC and REST style protocols. And the idea then was to take this and basically treat a call from the Java V8 engine to the C++ world basically as a remote call without basically the network part. So what basically happens is
Starting point is 00:24:47 when you call a C++ method from JavaScript is the method call argument from JavaScript will be kind of serialized into a C++ representation suitable for remoting. And then over the remoting infrastructure, we just call the method of the C++ class. And then the result is again transferred back to JavaScript. So it basically all happens in the same process
Starting point is 00:25:22 without the overhead of first putting everything into a serialization format. So it's actually pretty efficient. Not quite as efficient as if you'd create specific V8 wrappers for a C++ object, but the difference in performance can be neglected. So you wrote your own code generator to do this, right? Right. Actually, the first version of the code generator was back then written by an employee of mine, but I've since taken over maintaining it.
Starting point is 00:26:01 So is it from scratch, not Clang-based? Yeah, it's from scratch. The project was started around 2007 or so. So it was before Clang. And actually, one of my goals for the future is to use Clang or libclang as a frontend to parse the header files and then just do the code generation. Because also the header file parser that we wrote was handwritten.
Starting point is 00:26:35 It's also basically the same parser that is used to generate the reference documentation for the Boko libraries. Oh, okay. It has some, as you can imagine, it's not capable of passing any possible C++. That would be very difficult to get right. Yeah. I wanted to interrupt this discussion for just a moment to bring you a word from our sponsors.
Starting point is 00:27:03 You have an extensive test suite, right? You're using TDD, continuous integration, and other best practices. But do all your tests pass all the time? Getting to the bottom of intermittent and obscure test failures is crucial if you want to get the full value from these practices. And Undo Software's live recorder technology allows you to easily fix the bugs that don't otherwise get fixed. Capture a recording of failing tests in your test suites and debug them offline so that you can collaborate with your development teams and customers. Get your software out of development and into production much more quickly and be confident that it is of higher quality. Visit undo-software.com to see how they
Starting point is 00:27:41 can help you find out exactly what your software really did as opposed to what you expected it to do. And fix your bugs in minutes, not weeks. So what kind of difficulties did you have with integrating JavaScript and C++? The first one was getting to know the V8 library. The documentation is not too extensive. Basically, what you end up doing is go through the
Starting point is 00:28:11 V8.h header file and try to figure out things yourself. There is some introductory documentation that tells you the basic concepts, which is quite helpful. Then, if you go further, you have to go through the header file yourself and figure things out. And the first issue I stumbled upon is when I started, I used an early version of V8.
Starting point is 00:28:37 Then at one point, I upgraded to a new version, which means some of the V8 APIs that have been used changed. So I had to rewrite a little stuff. Things are a bit better now, and I guess the API has a bit more stabilized. So this is mostly fine now. Then the other issues were actually dealing with the different ways that you write code with regards to budget rating and things like that, and also the memory model. So the first one is memory management. JavaScript is garbage collected. So the way that you actually, or let me put it differently,
Starting point is 00:29:40 there are actually now two ways to make C++ classes available to JavaScript. The first one is using V8's mechanism, basically providing C++ wrappers for C++ objects that translate between JavaScript types and C++ types. And the other one is using the code generator and remoting that I talked about. Remoting is the easier part because in this case, we have kind of a service model where we have a fixed number of C++ objects or put it differently, the lifetime of the C++ objects is not controlled by JavaScript. It's controlled by some other code that creates and registers the service objects. So this is not an issue. What makes things harder is there are certain classes in Poco
Starting point is 00:30:40 like HTTP client that are made available in JavaScript using a handwritten wrapper. And in this case, it's actually possible in JavaScript to create a new instance, for example, of the HTTP request class. And if you do this, I have at the same time create an instance of the Boko net HTTP client session class, because this is what the JavaScript wrapper actually uses. Now, when you no longer need an object, at some point in time, the garbage collector from the V8 engine will run.
Starting point is 00:31:17 And what you can do in this case is you can register a callback function, and this will be called when the garbage collector deletes or removes the javascript object and you can use this to also delete your c++ object okay the funny part now is when your script ends and your script is done and it ends, then what V8 does, it simply deletes the entire JavaScript heap as a whole and does not call the callback function for each object. So what I had to do in this case, I have to keep track basically of every C++ object that is created in JavaScript.
Starting point is 00:32:05 And when the script ends, I have to check which objects are still there and manually delete them. So this was... Okay, now you're making me think of a question that I had already, which was V8 is not thread-safe, I believe, and yet your libraries do run in a multi-threaded environment and now you're also trying to keep track of some manual garbage collection in this multi-threaded environment with an engine that's not multi-threaded how have you sorted all that out
Starting point is 00:32:35 actually the the v8 engine is multi-threading capable so you can have multiple scripts running each in their own thread. What you cannot do is mix threads in a single script instance. That's not possible. So this one can be pretty well managed. And what we do in Machina.io is we have the possibility to start multiple scripts concurrently and just work independently of each other. So this is not much of an issue.
Starting point is 00:33:11 Okay, so it doesn't do... Okay, go ahead. Also, the kind of programming model that we have in Machina is different from, for example, Node.js. Basically, Node.js JavaScript runs from when you start Node.js till Node.js terminates, so you don't have the problem of having to clean up C++ objects. And in Machina.io, scripts basically can run independently, or the lifetime of scripts is independent from the lifetime of the whole application container. So scripts can start and stop arbitrarily within the lifetime of Machina.io application. And this is why we had these issues with cleaning up our memory.
Starting point is 00:34:06 Right. So what types of hardware does Machina IO support? Is it any embedded hardware that is capable of running Linux? It's basically any device capable of running Linux with about, let's say, 64 megabytes of RAM and a healthy amount of flash memory, also about 32, 64 megabytes. That seems pretty mean.
Starting point is 00:34:36 We may be able to run it on a smaller device, but it's actually hard nowadays to get this kind of smaller device. Right. And what types of features does it provide? You said it gives you the web client, web server, and it does sensor integration. Is that right?
Starting point is 00:34:54 Yeah, it has a couple of interfaces for different kinds of sensors, things like temperature sensors, also GPS receivers, serial port. Also, it supports a number of protocols like ModeBus, which is used frequently in the automation space. I have a couple of other protocols that we'll support in the future. Then it supports MQTT, which is a protocol that is widely used to send sensor data to cloud services, for example. Of course, HTTP. It has a built-in web server, so you can easily also write web interfaces also in JavaScript. So basically one of the features is you can do things like similar to PHP or JSP pages using JavaScript. A nice feature that it has is the web interface has a built-in JavaScript editor, so you can actually go to your device with a web browser,
Starting point is 00:36:08 open the JavaScript editor and start writing a JavaScript and run that script directly on your device, which is very useful if you want to quickly test some things out. Wow. It has software management based on so-called bundles which is kind of a bundle is kind of a zip file that combines shared library some metadata can also contain scripts and so on you can specify dependencies it's for people come from from with a Java background the Java has a similar technology called OSGI,
Starting point is 00:36:46 and we've basically done kind of a C++ adaption of OSGI. So it's actually quite rich on features. So what's the current status then of Machina? Is it production-ready? How's it looking? It's kind of uh production ready although uh we're still building different kind of additional features but i have the first customers already using it in new projects so there will be some devices coming out in the next couple of months using it already. Cool. And is Machina an open source project or a licensed product?
Starting point is 00:37:32 It's an open source project. It's basically under the Apache license, except for Poco, which is under the Boost license. Okay. And are you the sole contributor, or do you have other developers contributing to Machina as well? Right now, I'm mostly the only contributor. I have had a couple of contributions already, but no regular other contributors. I hope this will change in the coming months.
Starting point is 00:38:04 Okay, cool. I took some time with the P poker libraries to get some contributors, and now we have a pretty nice number of people working regularly on it. So I hope to manage at some point the same with Mac and IO. Okay. Jason, do you have any other questions? No, that's all I have. Okay, well, Gunter, it's been great having you on the show
Starting point is 00:38:26 where can people find you and find more information about Makina.io online? There is a website at makina.io the project itself the source code is on github you can also google my name
Starting point is 00:38:44 and it will be probably the first couple of free sites. Sometimes it pays off to have an uncommon name. Okay. Well, it's been great having you on the show today, Gunther. Thanks a lot. It was a pleasure. Thanks for joining us. Thanks so much for listening as we chat about C++. I'd love to hear what you think of the podcast. Please let me know if we're discussing the stuff Thanks for joining us. on Twitter and like CppCast on Facebook. And of course, you can find all that info and the
Starting point is 00:39:25 show notes on the podcast website at cppcast.com. Theme music for this episode is provided by podcastthemes.com.

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