CppCast - C# and IL2CPP

Episode Date: September 21, 2017

Rob and Jason are joined by Josh Peterson to talk about C# and some of the similarities and differences between the Managed language and C++, he also talks about his work at Unity 3D on IL2CPP. ... Josh is a programmer working at Unity Technologies, where he focuses on integration and development of scripting runtimes for the Unity 3D game engine. He enjoys learning about CPU architectures and assembly language, including the recent development of an MOS 6510 emulator in C#. In his free time, he coaches a number of youth soccer teams and reads philosophy and theology. News Energy Efficiency Across Programming Languages C++ World Café Useful GCC warning options not enabled by -Wall -Wextra Josh Peterson @petersonjm1 Links Microsoft C# Guide Unity 3D An introduction to IL2CPP internals Sponsors Backtrace JetBrains Hosts @robwirving @lefticus

Transcript
Discussion (0)
Starting point is 00:00:00 This episode of CppCast is sponsored by Backtrace, the turnkey debugging platform that helps you spend less time debugging and more time building. Get to the root cause quickly with detailed information at your fingertips. Start your free trial at backtrace.io.cppcast. And by JetBrains, maker of intelligent development tools to simplify your challenging tasks and automate the routine ones. JetBrains is offering a 25% discount for an individual license on the C++ tool of your choice, CLion, ReSharper, C++, or AppCode. Use the coupon code JetBrains for CppCast during checkout at JetBrains.com. Episode 119 of CppCast with guest Josh Peterson recorded September 20th, 2017.
Starting point is 00:01:01 In this episode, we talk about C++ user groups around the world and GCC warnings. Then we talk to Josh Peterson from Unity3D. Josh talks to us about C++ developers by C++ developers. I'm your host, Rob Irving, joined by my co-host, Jason Turner. Jason, how are you doing today? I'm doing pretty good, Rob. How are you doing? Doing good. You have a little chaos going on in your house right now, though, right? Yes, my house is currently being inspected by a team of 25 home inspection students.
Starting point is 00:01:57 We volunteered it for that. But on a side not related to my house being inspected at the moment, is I have been like, I really wanted to hit the goal of getting 10 000 subscribers for c++ weekly before cbp con this year at this exact moment i'm at 9999 so hopefully i will actually get past 10 000 subscribers so by the time this episode airs hopefully you've hit that but if not and you're listening and you haven't subscribed c++ weekly go uh go check out the youtube channel i think that sounds like a great plan well i get like 15 subscribers a day on average new subscribers a day so i really expect like i you know by the end of the episode to be at 10 000 but it's an exciting moment for me so i
Starting point is 00:02:40 thought i'd share it yeah 10 000 is a lot lot. You got there pretty quickly, it seems. Well, it might feel that way to you. How many episodes are you on now? 83 episodes. 83 weeks I've been doing it straight. Wow. Okay. Well, at the top of your episode, I'd like to read a piece of feedback.
Starting point is 00:02:59 This week we got an email from Harold, who is one of the organizers for the Sweden C++ user group. And he wrote in to tell us about this joint user group meeting, a distributed user group meeting between the Sweden C++ group and the London C++ group, which is pretty interesting. Yeah. I guess in London and in Sweden, Stockholm, where the two groups meet, the company King has a headquarters in both locations or building in both locations. So they're holding the meetup
Starting point is 00:03:36 and they're going to basically take turns presenting content. So London will present some, Sweden will present some, and the other group will be watching it online, which is pretty cool. Yeah, and since I guess there's an hour time difference between the two of them, they're doing like one of them's doing lunch at the front or dinner at the front end, one's doing the dinner at the back end or something like that.
Starting point is 00:03:53 That looks like a neat setup. Yeah, I'm not sure if they're broadcasting any of the content to people outside of the user group or if it's meant just to be for the people in the user group. But if you're in London or Sweden, and you're not regularly going to this user group already, it's probably worth checking out. Yeah, and that's October 26th, it looks like. Yes.
Starting point is 00:04:15 Well, we'd love to hear your thoughts about the show as well. You can always reach out to us on Facebook, Twitter, or email us at feedback at cpcast.com. And don't forget to leave us a review on iTunes. Joining us today is Josh Peterson. Josh is a programmer working at Unity Technologies, where he focuses on integration and development of scripting
Starting point is 00:04:33 runtimes for the Unity 3D game engine. He enjoys learning about CPU architecture as an assembly language, including the recent development of an MOS6510 emulator in C Sharpsharp. In his free time, he coaches a number of youth soccer teams and reads philosophy and theology. Josh, welcome to the show.
Starting point is 00:04:53 Hey, thanks for having me. I'm glad to be here. Interesting that you specifically call out the 6510 version. Yes, I'm probably not as versed in all the versions as you are, but I guess 6510 was maybe a little more memory than 6502, right? Is there another difference? I'm not sure. As far as I know, the only difference is that the 6510 has an I.O. port on it. Okay. Yeah, there's plenty of people who know the mods, those processors,
Starting point is 00:05:21 much better than I do, but I thought it would be a fun one to try to write an emulator for. I know there's at least three people listening to this podcast when it airs who would correct us on everything that we just said. Please do, because I'd like to know more. Do you have a specific goal for a system that you want to emulate, or just the CPU? I do. I'd like to put together something for playing with assembly language or learning assembly language. I thought the assembly language for the MOS 65
Starting point is 00:05:49 100 series is pretty simple. It's a CPU that I could write an emulator for. I know there's already some out there, too. I think there's at least one website that does it in JavaScript and you can actually type in the assembly code and see it execute. I had something like that in mind, but we'll see.
Starting point is 00:06:06 Yeah, I actually used that JavaScript 6502 website when I was preparing for my CppCon talk last year. It was handy. Yeah, it's really nice. But it was fun writing the emulator. I learned a lot about 6502 and CPUs in general. Yeah, my cousin, one of his hobbies is every time he picks up a new language or a new system
Starting point is 00:06:30 is to port his Nintendo emulator to it. So he has done one, I believe, in C Sharp and in TypeScript and Rust and C at this point. Wow. And the 8-bit Nintendo? Yeah. So that would be a 6502, right? Yeah, which is why I brought it up.
Starting point is 00:06:48 So yeah, maybe I don't fully understand the 6510 to 6502 distinction, but hopefully someone will help me out. Yeah, yeah. There's no reason to get into the weeds there. I can think of this. Anyhow, I'm not sure. I would have to look to double-check. Okay, Josh. Wellosh well we got a couple
Starting point is 00:07:06 news articles to discuss uh feel free to comment on any of these and then we'll start talking to you more about uh the work you're doing at uni and c-sharp and il2cpp okay okay okay uh so this first article uh is this paper about energy efficiency across programming languages. How does energy, time, and memory relate? And I don't know about you guys, but I didn't read the whole paper, but I did browse through the set of results a little bit and was happy to see that C++ is always at the top of the chart. Not the very top. Usually C, C++, and Rust are kind of grouped in the top three positions between the different tests that they ran through.
Starting point is 00:07:49 Yeah, I find this slightly confusing, personally. Because I know, I read somewhere else that they based all this on the language shootout comparisons. So, I mean, there's already a suite of these tests for all these different languages, right? So they were able to run them. They didn't have to write their own suite of tests. So I expected to see a direct correlation between wall clock time and
Starting point is 00:08:11 power usage, but that's not what you see. So like looking at the binary tree comparison, C++ is actually one of the slower ones, but again, they're using someone else's thing. It's 63 seconds, even though it took it was only the second and the amount of cpu usage or excuse me and uh power usage yeah i don't quite understand
Starting point is 00:08:34 the difference there yeah that seems to be what we find a lot with especially on mobile platforms so you know the code that actually executes faster is better for energy, right? Because there's fewer instructions. Right. I do recall, it's probably maybe five years ago, I think Herb Sutter gave a talk about kind of the future of C++. I don't know if you guys remember this. I think it was right after C++11, but about how languages would be judged based on something like performance per watt.
Starting point is 00:09:03 I think it's what he said. And I don't know. It seems like this sort of analysis indicates that's becoming more and more the case with mobiles and data centers and whatnot. Languages which are energy efficient can be really beneficial. So we don't want to be running all of our high-performance computations with Ruby or Perl, it looks like. If I were to take a quick glance at all of the bottom of the rankings
Starting point is 00:09:32 across these tests. Yeah. Python's really pretty low down there, too. Yeah. Interpreted languages without any sort of compile time optimization or anything. You know? Yep. Okay. languages without any sort of compile time optimization or anything. Okay, next one.
Starting point is 00:09:52 Jason, you were actually a part of this, the C++ World Cafe. I was. We were just talking about that distributed user group. This seems like kind of a similar thing, a user group happening online. Am I right? Well, no, it's kind of the inverse in a way, I guess. They had their user group that was meeting in Germany, and they had the four of us call in to people running Skype on their laptops.
Starting point is 00:10:19 So we were just four, specifically four individuals joining in with this one user group. And I didn't interact with any of the other people who called in. I was just interacting with the table that I was at. It was interesting. But it was a lot of fun, actually, from my perspective, because apparently I was just available to keep chatting. So I just stayed on the line with them for, I don't know, over an hour or something, and just got the chance to just chat with some of our C++ users in Germany and talk to them about their experiences learning C++ and
Starting point is 00:10:50 stuff. I had a great time doing it. Cool. And your topic was how can I become a better C++ developer? It looks like, and I saw there, there's a transcript of the conversation that all you and the other three guests were having. Is it not recorded, though? Is it just the transcript? I thought, oops, I thought that there was going to be a video posted also. But it's been actually a while ago that we did this. It took him, you know, understandably, yeah, June 14, took him a while to go through and like organize everything and type out all the transcripts and double check it for errors and whatever but i agree i don't see a link to the video so that
Starting point is 00:11:30 must not have gone up okay well i really like the idea of these kind of online user groups and distributed user groups uh you know just more ways to bring the community together yeah yeah okay and then the last one we have today is useful gcc warning options not enabled by w all and w extra and i thought a couple of these warnings were uh seem to be pretty useful it definitely seems like uh you know maybe they should be included in w all w extra i don't know who makes that decision i just i, I find it ridiculous that there's this flag called all, which is not all. And then there's a flag called extra, which is more than all, but still not all. But, you know, it's historical.
Starting point is 00:12:16 They don't want to risk enabling too many warning options that are going to break people's builds who compile with w air but um i'm not that nice i guess if i were a compiler developer i'd turn them all on well i wonder is there is there a a way or a possibility of moving kind of warnings into the standard you know so you could say these are the standard set of warnings that all compilers should implement and maybe they have a standard wording or a number system yeah there was who did we talk to about that patrice briefly or something possibly the possibility of something like that maybe someday happening but i think it would take so much effort to get everyone to agree but i think we have we have two things right now that i think virtually everyone agrees on I think it would take so much effort to get everyone to agree. But I think we have two things right now that I think virtually everyone agrees on,
Starting point is 00:13:10 that falling through switch conditions is maybe not something you want to do, and unused variables is something that maybe you don't want to do. And so then we have the attributes in C++17 for those two things where we can selectively disable them when we want to. But creating a consensus on what everyone agrees should be a warning, I'm guessing, would be...
Starting point is 00:13:33 Well, maybe you should volunteer, Josh, to spearhead that. I guess it's not surprising that you say that. That makes sense, right? If it's your idea, then... That wasn't my idea. You said there should be a standard set of warnings. Oh, okay. No, I'm sure other people have had the same idea.
Starting point is 00:13:52 Maybe someone else will. Maybe I will. But I guess if there was at least maybe a framework in the standard for, like you said, maybe those two go in first, and that's easy because everyone agrees, and then you can incrementally pull in other ones. I know we can get into this later, but we have a tool that generates C++ code, and we work hard to have that be warning-free,
Starting point is 00:14:10 which is really difficult across multiple compilers. So we have to figure out, are we going to ignore certain warnings or are we going to pragma them out? Well, you know, I mean, maybe we can talk about that briefly now since you just brought it up. Why do you do that?
Starting point is 00:14:29 Do you, if you work with GCC and Clang, do you, what warning levels do you guys use? So for the code that we generate, okay, so maybe we'll back up real quick. So one of the main tools I work on at Unity is called IL2CPP. And that's something we'll definitely dig into in a minute, right? Yes.
Starting point is 00:14:49 Okay. But the idea is it converts.NET bytecode to C++ code. Okay. And then we try to do as best as we can have that C++ code compile without warning. So in our internal tests, we turn on W error on GCC and Clang. And I don't remember what the flag is on Microsoft compilers, but the same flag. And then we go through and we disable maybe a half dozen warnings that we know that we have problems with. And we kind of try to pick those off, you know, over time.
Starting point is 00:15:21 Because of the nature of some differences between the.NET runtime and the way IL works and the way C++ works, there are some kind of impedance mismatches that prevent us from turning off all the warnings. Okay. But, um, but the idea is basically in our test code we do that. And then, uh, in our, for our users, they run the same tool and then they'll compile it on their machine with a platform-specific compiler. Um, in that case, we don't apply WArror. We want it to compile even if there are still warnings on their machine with a platform-specific compiler. In that case, we don't apply WArror. We want it to compile even if there are still warnings on their machines. And that's to catch cases where we may be missing something in our test suite, like it's a bit of IL code that we don't have covered in our test suite yet.
Starting point is 00:15:56 And so we'll generate a warning that we aren't expecting or something. Okay. We'll definitely have to dig into all of this a lot more in a minute. Yeah. We'll definitely have to dig into all of this a lot more in a minute. Yeah, so let's back up a little bit and start out by telling us a little bit about your job at Unity3D and kind of why you live in both the C Sharp and C++ world. Sure, so Unity Technologies is a company I work for which makes the Unity3D game engine. I think it's relatively well known by now. I think we've been around for 10 or 15 years.
Starting point is 00:16:25 I'm not sure exactly how long. But in any case, the Unity 3D, the game engine, is mostly written in C++. The scripting language exposed to users is C Sharp and a few other languages we can talk about, but mainly C Sharp. And so things are built on top of a.NET runtime. In the.NET world,
Starting point is 00:16:52 there's a couple of different runtimes. There's Microsoft's, they actually have a few. And there's a pretty cool one called Mono, which is an open source project to implement a.NET runtime, a C-sharp compiler, all these different tools that you need for a whole.NET environment and ecosystem. And that's been around almost since.NET has from Microsoft. So Unity is a native application written in C++ that hosts the mono runtime internally. And so then users can write C-sharp code. We run the C-sharp compiler on that code, and then we execute that code with the Mono runtime inside the Unity application. And so the role of my team is to, we maintain the integration with Mono, and we also work on new development in that area. So that involves things like integrating the C Sharp compiler into our tool chain and into our user's tool chain, making sure the runtime works across all of the platforms Unity supports,
Starting point is 00:17:45 which is a pretty large number. I think it's something like 20 or 30 now. Basically any platform you can play a game on, you can write a game in Unity for. So we maintain that across those platforms. And then the other thing we've done is this thing we call IL2CPP, which, like I said earlier, translates IL bytecode. So's kind of the the stuff that dot a dot net runtime executes it translates that into c++ and then we compile that with a platform specific compiler
Starting point is 00:18:14 and then we have an implementation of the dot net runtime so the same thing that that mono does from the runtime side of things we We implemented that in C++, and then we can execute our generated C++ code, and it uses our C++.NET runtime to make everything work. So my team developed the IELTS CPP technology, and we maintain it, and we maintain the Mono integration with Unity. So maybe we should start off by talking a little bit about IL and kind of the differences
Starting point is 00:18:46 in what a C Sharp compiler produces and what a C++ compiler produces. Yeah, I think that makes sense. So when you compile C Sharp code, you get this thing called IL, which I guess I should have mentioned that's called intermediate language. So it's a bytecode format. A lot of languages have a similar bytecode format. I think Java does and maybe some interpretive languages have a similar bytecode format. I think Java does, and maybe some interpretive languages. I'm not entirely sure. But IL is kind of like assembly. You can think
Starting point is 00:19:10 of it like that. So it executes on top of a virtual machine. And the virtual machine is often called the.NET virtual machine. It's kind of like a real CPU, but without registers. So a lot of virtual machines operate like this. They're stack-based, so they have the concept of memory in the sense of a stack. So I can push and pop things onto a stack, and then I can call functions. I can do really simple flow control with go-tos. I can define types, structs, and classes, these kind of things. All that stuff works in IL.
Starting point is 00:19:44 So C Sharp Compiler emits this IL, and then anybody who can execute that IL, anybody who implements a.NET virtual machine can run the IL. And there's kind of four big virtual machine implementations out there right now. So Microsoft has the.NET framework, which is kind of the classic one that's been around for a while.
Starting point is 00:20:04 They've recently built a new one called.NET Core. And that's fully open source and portable across, I think, Windows, Linux, and Mac, and maybe a few other platforms now. And then Mono, which is the one that Unity uses. And then IELTS and CPP, the one we developed internally. There might be others, but those are kind of the four biggest ones as far as production use that I'm aware of. So C++, of course, is different because C++ compilers are emitting machine code
Starting point is 00:20:34 directly for whatever operating system and architecture that you're compiling for. So I can imagine if you're a C Sharp developer, I can compile this code down to what's called an assembly which would be like a DLL or an executable in.NET and that's just an IL bytecode and I can take that assembly to any
Starting point is 00:20:54 platform that supports.NET I can take the same assembly to Mac, Linux, Windows any place that can execute.NET and execute it and it theoretically should execute the same way if the.NET virtual machine is working properly. And of course, with C++, that's not possible. One of the other cool things about IL from a developer perspective is it can be disassembled pretty easily.
Starting point is 00:21:18 So there's a couple of utilities out there. One's called IL Spy, which is an open source project. And JetBrains has one called DotPeak. And both these two utilities can take an IL assembly that was generated from a C Sharp compiler, or really from any compiler that supports IL, and you can fully inspect it. You can see all the IL code with pretty high fidelity. So it's interesting if you're a C Sharp developer and you're thinking about, you know, I want to get involved in C++, right? A big thing about C++ is being really close to the machine.
Starting point is 00:21:50 You can often reason about, how is my C++ code going to look like in the target machine language? And you can use Compiler Explorer or tools like that to really actually see that. It's a little more difficult to do that with C Sharp because you've got that.NET runtime, which is doing the actual conversion to machine code see that. It's a little more difficult to do that with C Sharp because you've got that.NET runtime, which is doing the actual conversion to machine code for you. But it is really easy in C Sharp to see the IL code. And if you can take your C Sharp assembly that you compiled,
Starting point is 00:22:16 use one of these tools to disassemble it and look at the IL, I think that's really beneficial because you can see what constructs in C Sharp create a lot of IL, which ones create a small amount of IL. And really, if you can understand IL, you can understand most assembly languages. They're really similar. So I spent a little bit of time last year
Starting point is 00:22:34 looking at the Java bytecode generated by the Java compiler. And I was kind of surprised to notice that it did, like, no optimization at all. And it seems to be that their argument is well the uh you know the jit will take care of that i'm curious how much of a is it like a one-to-one correlation from your c-sharp to your il or does it do optimization like we would expect the c++ compiler to do i think most c-sharp compilers are not doing a whole lot of optimization okay um they're getting better so mic Microsoft's compiler, Roslyn,
Starting point is 00:23:06 is kind of their new compiler framework, which is open source. And it does more optimization than their previous C Sharp compilers did. But a lot of the work is still done by the runtime. So Microsoft has a new JIT run. Okay, maybe I should back up. So an acronym JIT is useful here.
Starting point is 00:23:30 It's a just-in-time compiler. That's how most.NET, and I think, I'm not sure about Java, but I think Java's the same, but most.NET stuff works via JIT, right? The IL code is JITed, so it's compiled on the user's machine to machine code kind of as it's executed, and then that compiled binary is saved for the next time the same function gets called or something and you reuse it. It doesn't rejit. So Microsoft has a pretty new JIT compiler for IAL called RyuJIT, and it does a lot of optimization. So the kind of things you'd expect in a C++ compiler to do, the kind of things you
Starting point is 00:24:02 see in Clang or GCC from different types of optimization passes, the JIT compiler does that. So I think in the end, the goal of the C Sharp compiler is to produce IL, you know, that the JIT compiler can work with, but it's not doing a significant amount of optimization. Interesting. Okay. Okay. John, talk a little bit about some of the main differences that people think of between a managed language and C++. I say new list of int or something like that, right?
Starting point is 00:24:48 That's going to tell the C Sharp compiler, hey, I want to create a new object, and I want the garbage collector to manage that memory. So there's no need in C Sharp to deallocate or call free or delete or any of the things we see in C++ because the garbage collector will track all the references to that memory and it'll remove the memory whenever it sees fit when nobody's referring to it anymore.
Starting point is 00:25:12 There's similar concepts between C Sharp and C++ in the sense of the heap and the stack. So both languages have that capability to either allocate things on the stack, just a small scope or a function scope, or allocate things on a heap. The difference with C++, of course, is when you say new, right, you get a heap allocation.
Starting point is 00:25:31 It's up to the programmer to specifically free and deallocate that memory. As a C Sharp developer, you know, you don't think too much about that in a lot of cases, right, because the GC handles it. But at least from the perspective of the code we see in Unity, that can matter because the GC is non-deterministic. So if I'm doing a game or maybe even a server application where I need to have some sort of a
Starting point is 00:25:57 response time guarantee, the GC can really be a problem. Now the better the the better the gc implementation is the less of a chance that'll be a you know be an issue but you can still get a non-deterministic you know time where your application is stopped because the gc has to go do something so there are ways in c-sharp to avoid garbage collection there's kind of two different categories of types, I guess is the best word in C Sharp. You have reference types and value types. So in C Sharp, something like an int or a double is a value type. It's never allocated on the GC heap. It's always allocated on the stack.
Starting point is 00:26:39 And then a class, a user-defined class, is a reference type, which is always allocated on the GC heap. And you have this kind of in-between type called a struct in C Sharp, which is a little different from C++. So creating a struct in C Sharp is a user-defined type, but by default, it's going to be allocated on the stack. And that gives you really tight control of the memory then. If you want to write C Sharp code with structs and value types, you can use kind of scope based memory management in a sense, because you're not going to the garbage collector. But if you're coming to coming to C plus plus from C sharp,
Starting point is 00:27:14 you know, you need to consider the fact that you have to do something to free that memory, right? And of course, in modern C, C plus plus, that's not calling new and delete, right? We want to pretty much avoid those. If you're using, what, C++11, maybe C++14 or later, unique pointer and shared pointer and all the tools you need are there in C++. So I think it's certainly possible in modern C++ to avoid any manual memory management in most cases. So I'm thinking about from a programmer, what I'm thinking about as a programmer, what I'm thinking about as a programmer
Starting point is 00:27:47 in C Sharp and C++, things are pretty similar. If I'm using modern C++, I don't think about memory management too much as long as I use the right types. Okay. But I guess behind the scenes, there is a difference.
Starting point is 00:27:57 I think, was it CppCon last year, Herb Sutter? Did it talk about the memory management in C++? Introduce new pointer types, that kind of thing of thing yeah yes yeah i remember he had a slide or something with a table that was really excellent it had you know if i want something to live this scope i do this and this scope i do this and it kind of broke it down really nicely right um for a developer so i think if you're coming from a managed language something like that would be really beneficial to kind of understand what are the what are the idioms in modern c++ for memory management that can avoid the need to, you know, have dangling pointers and incorrectly freeing things or double freeze and all these
Starting point is 00:28:34 kind of problems you can run into when you're doing kind of like more C-style memory management. So with IL to CPP, you're taking the IL, you're recompiling it to C++, so it has some sort of interoperable intermediate layer of some sort so you can bridge these concepts. How does that work? So in the C++ code we generate for IL to CPP does run in a garbage-collected environment. So it's C++ code, but we actually are using a garbage collector in our runtime implementation.
Starting point is 00:29:09 Okay. So the garbage collector is really in the.NET runtime. So anytime somebody says in C Sharp new, there's a certain IL instruction, a single, you know, if you could call it an assembly instruction, one instruction IL, which is a new object. And that's to say,
Starting point is 00:29:26 create an object of this type from the GC. Okay. And so that goes to the runtime and says, GC, I need, you know, 40 bytes of space for this object. Give me back a pointer with 40 bytes of space. And any.NET runtime is going to have to do this. And then it's the job of the runtime and the GC
Starting point is 00:29:44 to keep track of all the references to that thing and correctly garbage collect it. But out of CPP, although we're converting to C++ to get the code generation, we're still using a GC. So it's still a full.NET runtime. So did you actually, like... I'm now becoming, like, weirdly curious about what the actual generated C++ looks like.
Starting point is 00:30:04 Did you, like, make your own operator new and that kind of thing to generate garbage-collected pointers? Or are you using allocators? Or are you just doing something completely different, like some sort of library implementation? It's really in a library implementation. There's a function that gets called into our runtime library, which says, hey, I need
Starting point is 00:30:25 a new object of this size from the GC. So it's not an overloaded operator new. Okay. So how do you then... And then, yeah. I was just wondering how you keep track of lifetime and knowing that, you know, things are referencing this thing that you just made. So that's where the garbage collector comes in.
Starting point is 00:30:43 So right now we're using the BOM GC, which is actually written in C. And Hans BOM, I guess, who's well-known in the C++ community, wrote it, and it's still maintained. But it's what's called a conservative garbage collector. So that means that whenever it needs to run a garbage collection, it's going to have to stop all the threads in the program, and it's going to scan for things that are called GC roots. It builds a directed graph, basically, of all that memory access is and all the relationships between objects that it knows about. The GC roots are what determine what's alive and what's not.
Starting point is 00:31:19 We have the option of allocating specifically, say, this object is a GC root, and it's going to live for so long in the program. But it also locates GC roots by looking at the call stack for each thread. So it'll say, on this thread, look through the call stack, find all of the local variables that are sitting on the stack. Any of those that might be references to something which is GC memory, keep track of those. Okay. Yeah, so that's really how that works and kind of how we implement the.NET
Starting point is 00:31:52 runtime. And different runtimes and different garbage collectors have different ways to handle that. Okay. Since we're talking about memory and garbage collection right now, maybe we could talk about the differences between constructors and destructors between the two languages, because I think that's another thing that can be pretty different. That's true, yeah. So constructors are relatively similar. I mean, the constructor kind of sets up the invariance for your class or your type, right, the same way in C Sharp and C++. And actually, it's interesting to kind of see as languages kind of cross-pollinate ideas, right? So C Sharp has had, I think they're called forwarding constructors maybe for a while, where one constructor can call another one.
Starting point is 00:32:31 And I think C++ got that at C++11, which is a really nice feature for kind of organizing class initialization, especially if you want to provide a different interface to initialize a class in different ways. So in that respect, constructors are pretty similar. Destructors are very different. So they're spelled the same way, right? If you look in code in C Sharp and C++, you see tilde, you know, type name or something, right, for both destructors, but they're totally different. In C Sharp, because it's garbage collected,
Starting point is 00:33:01 there's no guarantee about when an object will be deallocated. Even if it's no longer referenced at the end of a function or when a class goes out of scope, the garbage collector may not have an opportunity to actually collect that memory anytime soon. It's totally non-deterministic. So the way that works is there's the destructor, which is also called a finalizer in C Sharp sometimes, will get executed at some arbitrary time. In some. time. Um, in some.net runtimes that's at,
Starting point is 00:33:28 that occurs on a background thread. So for Alta CPP on most platforms, um, we have a separate thread that runs that, that calls finalizable objects and says, okay, the garbage collector is done with you. I can call your finalizer now call your destructor.
Starting point is 00:33:41 Um, that means in C sharp, you have to be really careful about what you put in a destructor. You can't have references to any other objects that might be on the heap because they may have been called before or after you. They're destructors, you don't know. So you're really restricted.
Starting point is 00:33:55 You know, where C++, because we have the scope-based, you know, resolution in RAII, which is that resource acquisition is initialization. That acronym always, it's a confusing formula. But basically, right, when you exit a scope, in RAII, which is that resource acquisition is initialization. Yes. That acronym always is a confusing formula. But basically, right, when you exit a scope, the compiler is going to make sure that any types in that scope have the destructors called at a deterministic point, right?
Starting point is 00:34:15 Yes. So as soon as you leave that scope, they're called, and they're called in a certain order. I think based on the order they were declared in that scope. Reverse order, yeah. So it's really deterministic. So the key thing is that difference in determinism. So in C++, I can have more freedom in a destructor.
Starting point is 00:34:30 I guess still not total freedom, right? We don't want to do things like throw from destructors. Sure. Ugly things like that. But I can have a lot more freedom in destructor because I can know and I can reason about in the code when they'll be called. So in C Sharp, I can't do that.
Starting point is 00:34:41 So I think for most C Sharp programmers, I've learned at least that you really don't want to put any code in a finalizer or a destructor unless absolutely necessary. That's always like a last resort. And I know I've been bitten by four by putting code in there and bugs come up because, oh, I didn't think it'd call it in this case or at this time or something like that. I mean, in C Sharp, what code would you put in a destructor
Starting point is 00:35:05 if you have no idea when it's going to execute? It's really tough. Sometimes it'll be, a lot of times if it's objects that have a native or an OS level thing kind of behind the scenes, they have to manage like a file or a thread or a socket or something in the OS level that's not part of the managed language system you'd put there. So if you're all working in a managed code, yeah, you almost never write a destructor. or a socket, or something at the OS level that's not part of the managed language system, you'd put there.
Starting point is 00:35:26 So if you're all working in a managed code, yeah, you almost never write a destructor. But once you start calling into, you know, pick up these things that don't work with the C Sharp GC, you may need to say, if I have a wrapper class that manages a file, for instance, like I need to make sure that when the finalizer's called,
Starting point is 00:35:40 if the file handle's still open, it gets closed, so I don't leak it. That's probably the thing I've seen in most cases, something like that. The one thing that is in C Sharp, which is similar to a C++
Starting point is 00:35:56 destructor, is this interface called IDisposable. It has one method called dispose, and that's kind of a cleanup method, similar to what a C++ destructor does. So if you're running C Sharp code, you can use a pattern with the using keyword, which basically says, I'm going to use this object,
Starting point is 00:36:14 and this object has to implement IDisposable. And then when we get, it's an open curly brace, then a bunch of code. And at the closing curly brace, the dispose method will be called. So you get something like RAII in C Sharp. So if you're a C Sharp developer, I'm guessing you might be familiar with that pattern,
Starting point is 00:36:30 with using an IDisposable, and that you could, in your mind, that's very similar to what C++ destructors do. The whole concept of language is when I don't know when something's going to be destructed, it just makes me uncomfortable. It can be really scary, yeah. And when you get to
Starting point is 00:36:51 working between C Sharp and C++ or working C Sharp with OS concepts that don't fit into the GC, it can become you know, there's some odd kind of bugs that can happen there. Right. I wanted to interrupt this discussion for just a moment to bring you a word from our sponsors. Backtrace is a debugging platform that improves software quality, reliability, and support by bringing deep introspection and automation throughout the software error lifecycle.
Starting point is 00:37:19 Spend less time debugging and reduce your mean time to resolution by using the first and only platform to combine symbolic debugging, error aggregation, and state analysis. At the time of error, Bactres jumps into action, capturing detailed dumps of application and environmental state. Bactres then performs automated analysis on process memory and executable code to classify errors and highlight important signals such as heap corruption, malware, and much more. This data is aggregated and archived in a centralized object store, providing your team a single system to investigate errors across your environments. Join industry leaders like Fastly, Message Systems, and AppNexus that use Backtrace to modernize their debugging infrastructure. It's free to try, minutes to set up, fully featured with no commitment necessary.
Starting point is 00:38:03 Check them out at backtrace.io slash cppcast. Since you brought up just now the two of them working with each other, what are some of the ways C Sharp and C++ can interoperate? Well, usually they interoperate like a lot of languages through the C ABI because C++ doesn't have a stable ABI across compilers. So there's a method called P invoke or platform invoke, which I think was originally designed in C Sharp to access the Win32 API, which is a C API.
Starting point is 00:38:36 But it can really be used for any function that can be exposed as a C function. So you can define an extern function in C Sharp and then apply some attributes to it to tell the runtime, hey, this function maps to some native function in a given DLL or shared object of a given name. And what happens then, whenever the runtime, C sharp runtime, sees that method called, then you can, it'll say, oh, go look up that native function in that DLL, get a function pointer to it, and invoke that function pointer with the arguments. And then the arguments have to be mapped or marshaled, as it's called, from managed code into native code. So, for example, a string in C Sharp,
Starting point is 00:39:16 most runtimes represent a string as an integer, which is the length of the string, followed by UTF-16 encoded 2-byte characters to make up the content of the string, followed by UTF-16 encoded two-byte characters to make up the content of the string. And when you go to a C or C++ function with a string as an argument, that has to be copied into a char star, basically. And the runtime will allocate a buffer for that. It'll copy all the characters, do a conversion to, I guess, ASCII or UTF-8, and then provide a pointer to the native code with
Starting point is 00:39:46 that same variable in it, that same data. So what happens there is all the parameters and the return type have to be marshaled. One kind of interesting caveat that we see a lot in that case is, for example, functions returning bool make a lot of sense, right? You might want to call into native code or native library and ask, you know, a question, right? It returns a bool. Well, in C Sharp, a bool is marshaled as a four-byte integer because the capital B-O-O-L type in Win32 API is four bytes. Okay. But in C++, of course, a bool is one byte, right? Probably, yeah.
Starting point is 00:40:18 So I guess maybe it doesn't have to be. Yeah, I don't believe there's a requirement, but yes. Most implementations we've seen have one byte so i make a function call to a native method which returns me a bool and everything works great and now i turn on optimizations in my c++ build and uh-oh now like you know that that extra three bytes that in the you know in the debug build there was nothing was used there and it happened to be zero or something it worked out now that that's used by something else, and we get the wrong return value. So we have to explicitly
Starting point is 00:40:47 tell the C Sharp or the .NET runtime, hey, this is a bool return value. I want you to treat this as a one byte unsigned value, because otherwise you're going to treat this as a four byte unsigned value. So when you go from interop from C Sharp to C++, you kind of get these sort of
Starting point is 00:41:04 odd little characteristics sometimes. And you can hit performance problems if you're going across that boundary a lot because marshalling can be expensive to allocate and deallocate memory on a regular basis. And you can do the same thing in reverse. So you can take a C sharp function, and there's a method in the.NET standard library you can call to get a function pointer to it a C function pointer oh and then you can pass that C function pointer to native code
Starting point is 00:41:31 somewhere in C or C++ and you could wrap it in a std function or you know whatever you're whatever you're doing in in C++ or native code and you can call it later and when you execute that function there's a little wrapper around it that the.NET Runtime has created, which will say, oh, I see this is a managed method you're calling, so I'm going to marshal all the parameters back from native code to managed code. So again, if you had a char star on that argument list, it would allocate some managed memory with the GC,
Starting point is 00:41:59 build up a managed string, and then pass that managed string into the managed method that you asked to execute. This all sounds very expensive. It really is. It really is. Usually, the pattern that we see for this kind of thing is if you have some sort of a native library where you have a high performance, you know,
Starting point is 00:42:18 something that you can implement native code much faster, you can implement a managed code, right? And you want to give it a bunch of data. You say, okay, I'm going to give this native method some sort of data which is blittable, meaning that we can just do a direct memory copy from managed native code, so a big array of bytes or something like that.
Starting point is 00:42:36 Let's say I want to render something, and I have to give it to a native rendering code from C Sharp, so I can give it a big array of bytes, and it does the work for me and then returns. So anything that's kind of a chatty interface where you're going back and forth across this boundary pretty often is usually really expensive. And the.NET runtime is going to do a lot of work to kind of make that all happen that you probably don't see in the code immediately.
Starting point is 00:43:02 So, so yeah, but it's really beneficial, right? If you have, you know, code that's really beneficial, right? If you have code that's in both managed and native code, or you're transitioning from one to the other, you know, in a section of code, the ability to interoperate between them is, you know, absolutely necessary. Right. Okay, so now
Starting point is 00:43:18 I'm curious about IL to CPP again. We've talked about these costs, and we've talked about JITing, and now I'm wondering what the motivation was for making your own.NET runtime with the CPP again. We've talked about these costs and we've talked about jitting. And now I'm wondering what the motivation was for making your own.NET runtime with the C++ translation. So the motivation was twofold.
Starting point is 00:43:32 First of all, the biggest one was probably portability. And then a secondary one was performance. So because we support so many platforms at Unity, we're always looking for ways
Starting point is 00:43:43 to make our code more portable. Like the less work we have to do to bring up a new platform, the faster we can get many platforms at Unity, we're always looking for ways to make our code more portable. The less work we have to do to bring up a new platform, the faster we can get it to our users, the faster they can make games in it. That's really important to us. IELTS CPP is slightly different from the.NET framework and.NET Core and even parts of Mono because it's not a JIT.
Starting point is 00:44:01 It's an AOT compiler ahead of time. So IELTS CPP does not allow for runtime code execution like you would get in.NET. In.NET, I can actually say, in C Sharp, I can create a method inside code and then say, okay, go execute this method, right? ALTA CPP doesn't support that. It's only ahead of time compilation.
Starting point is 00:44:20 Okay. So with that in mind, basically ALTA CPP is converting IL code to C++, Okay. can take I-O code, can A-O-T it, and get machine code directly out without going through a.NET... without jitting through a.NET runtime. Okay. This is really useful for platforms like iOS and a lot of console platforms where runtime code execution is not allowed.
Starting point is 00:44:56 You know, the vendors or the operating systems don't prevent this, so PlayStation 4, Xbox One, you know, all these platforms are A-O-T only. You have to have pre-capable code. So the portability aspect is this. If we wanted to bring up a new platform
Starting point is 00:45:11 at Unity, we had to have a person who understood the architecture of the platform, the OS of the platform, assembly language for the platform, and the way that Mono's AOT engine works. Okay.
Starting point is 00:45:26 So finding developers with that skill set is really difficult, and even ones who are really good at that would be, you know, basically months to bring up a new platform sometimes. There's a lot of work there. So by taking the IL code and converting it to C++, now we have this representation of the code C++,
Starting point is 00:45:46 which really works well because it can, every platform that we have already has a C++ compiler. Usually those C++ compilers are really good at generating code. They can generate efficient code. They can usually generate better than, you know, handwritten code that someone could write into an AOT engine because they've got, you know got years and years of developer time put into them to generate efficient code.
Starting point is 00:46:08 So really it came down to portability. So we've taken our time to port our scripting engine to a new platform from maybe months to weeks using Alta CPP. So basically it means if I'm going to port to a new platform, I need to
Starting point is 00:46:23 do some back-end code to make sure that there's the C++ runtime section of IELTS to CPP. We call it lib IELTS to CPP, which is actually just normal C++ code that developers write that runs on the target platform. That has to be implemented for the target APIs, right? Sockets, files, threads, mutexes, all these kind of primitives need to exist and someone has to implement those that's not not too much code though but then all of the i.o code that we have to actually you know aot down to the machine level from the standard library and from all the user code that's always the same c++ code across all platforms all the cpp generates you know platform invariant code, basically.
Starting point is 00:47:07 So that gives us a nice portability win whenever we have to bring up a new platform. And then we do get, on some platforms, better AOT code, better machine code output, because, like I said, the C++ compilers are usually pretty good at that. We can pick up wins in a few other places. We've had benefits where the mono-AOT had to use double for floating point calculations,
Starting point is 00:47:28 and Unity is mainly a float engine, so we're getting really over-precision sometimes, and so some floating point scenarios, ALDA CPP generates faster code. Okay. But the real main focus was on portability and the ability to bring up new platforms faster. I'm wondering if it does it at all ease this difficulty in the interoperation between C++
Starting point is 00:47:50 and C sharp code that we were just discussing? So it really doesn't actually, which is kind of odd. I thought that it would when I first started here and started working on this. Oh, this is gonna be really easy, right? We're emitting C++ code, but it doesn't make it a whole lot easier because even though we're emitting C++ code, that C++ code is really just, you can think of it as an intermediate representation for machine code. I mean, that's what it's going to be.
Starting point is 00:48:14 Right. And so it still has to follow all the same rules that the machine code has to follow eventually as far as marshalling of parameters and return values and making sure that things are correctly hooked up to the managed runtime that we talked about so the interesting thing though is whenever you whenever you look at the c++ code that's generated by alda cpp for these marshalling cases and these p invoke cases you can actually see written in code the cost of it you can see oh look i have to iterate over all of the strings in this array, and I have to allocate code for each one, and I have to allocate memory for the array,
Starting point is 00:48:48 and I have to copy them all. Now I make the function call. And now I come back out of the function call, and this marshalling scenario may be one of the changes that remade a native code to be available in managed codes, and now I have to iterate the array again, reallocate new entries, copy all the data, and back over. Whereas when you're just looking
Starting point is 00:49:05 at machine code, that's really hard to see. Right. But it actually does not make the interop better in a sense of performance. There's all the same work has to be done. Okay. But you did, you did say that one of the motivations for IAO to CBP is performance, but the main motivation is portability. So is the generated C++ still something that the C++ compiler can optimize, or is it something that it's like, I have no idea what you're doing here? No, the C++ compilers do a really great job of optimizing it. I was kind of, you know, I've been worried about that in the past, but they seem to do really well on pretty much every platform we've seen.
Starting point is 00:49:43 Since IL has no flow control, everything's gotos, so the generated C++ code, it's really IL that's transpiled, basically. So you end up with gotos all over the place. There's no loops. There's some ifs, that's about it. But the C++ compilers do a really
Starting point is 00:50:00 good job. And one of the ways that we benefit is we can control how much C++ code is in a translation unit and what goes where. So we can really get some nice benefits out of inlining, especially without link time optimization. So LTO is really
Starting point is 00:50:15 nice when we're getting to a final product, especially for something that's high performance like a game. But for iterating in development time, LTO can be really difficult because it can take a long time to do link time optimization. So one of the things that we do is try to group together managed code that executes in the same places, like in the same types, into the same translation units.
Starting point is 00:50:38 And we'll generate really big translation units, maybe like 50,000, 60,000 lines of C++ code. Okay. And so that gives the compiler a lot to chew on for inlining, for example. Right. So we get, on most of the compilers we have, pretty much all of them,
Starting point is 00:50:51 we get pretty good optimization. We're very happy with the resulting machine code that we get out. That's very interesting. So IL2CPP works with the C Sharp Unity scripts for Unity games. Could a Windows C Sharp developer write an app and choose to compile it with IL2CPP instead of the visual C Sharp compiler and get some benefit out of that?
Starting point is 00:51:19 Not easily. I mean, theoretically it's possible. We can convert pretty much any IL code that came from a C's possible. We can convert pretty much any ILCode that came from a C Sharp compiler. We could convert, but we don't really have it packaged or available like that. Internally for testing, we do some things like that,
Starting point is 00:51:35 but our focus is really on the Unity customers and not on a general runtime necessarily, so it's not available in that respect, although maybe someday, I don't know. It's only technically possible. So why did Unity choose to use C Sharp as a scripting language?
Starting point is 00:51:56 So that's a tough question. That kind of extends back before my time at Unity. I think way back when it was just the founders, I think it may have been Python, actually. That's a terrible language for embedding. Yeah, I don't know the technical details, but I think at some point it was C Sharp and.NET were chosen. I think a lot of it had to do with Mono being an open source project.
Starting point is 00:52:19 And at this point, you know, I've been, like I said, 10 or 15 years on with Unity. You know, we're really happy like I said, 10 or 15 years on with Unity. You know, we're really happy with that decision to use C Sharp because the C Sharp ecosystem has really blossomed, especially in the last maybe three to five years with Microsoft, open sourcing a lot of things and really taking a renewed focus on it. I mean, the C Sharp ecosystem is pretty big. There's a lot of tools out there that really make it easy for developers to work in C Sharp.
Starting point is 00:52:43 So we like that. And one of the things like the reflection capabilities, you know, the jitting capabilities we can use in a lot of cases. We can kind of help users and guide them and protect them so that they can focus on making a game and not worry about, you know, as I think our CTO said in a recent talk, you know, the last thing we want is you to be, have this game ready to go, and two days before it's released, you find some random crash, you know, that you can't track down, right? That's, we've done something wrong if that happens and the unity side so so our goal is to you know make it as easy as possible and c-sharp provides a lot of safety and more
Starting point is 00:53:32 safety than you get out of c++ i think in that respect right um so that's really nice but uh yeah where why it actually originally started i'm not entirely sure i think it probably had to do with the the fact that mono was open source and was the product that was available that worked well. Now I feel like I should clarify, just in case I get some hate mail for saying that Python would be a terrible language to embed. The Python interpreter was never designed for embedding. And if you really want to dig into it, you can look into something called the global interpreter lock,
Starting point is 00:54:02 and it just makes things difficult. But anyhow. And that makes sense, too. That might also go into why Mono was chosen in C Sharp, is Mono was kind of from the beginning, I think, designed for embedding. Yeah. It can be run standalone,
Starting point is 00:54:16 and it has a really nice embedding API. So from Unity, we can call and get access to all of the Mono VM internals from C and C++ with very little friction. I've never used Mono specifically, but it's easy for me to believe since it was the same group of people that liked having a Lisp interpreter and Emacs kind of thing. So it's a lot of GNU guys that were working on it. Yeah, it's really a great technology. I mean, you look at all the things that they've done,
Starting point is 00:54:48 it's pretty incredible, actually, to fully re-implement the.NET ecosystem, basically, in an open-source way. Yeah, that's cool. Is Xamarin also based on Mono? Yeah, so Xamarin is, well, was a company, and Xamarin, I guess, is a product now, too, which is like using the Mono project for mobile development.
Starting point is 00:55:10 But Xamarin was recently acquired by Microsoft. So from a company perspective, it's part of Microsoft, but there's still the Xamarin iOS and Android and maybe a few other products out there. Going back to Unity and the scripting languages, you also support JavaScript, right? Does JavaScript do anything with AltaCPP? So it does.
Starting point is 00:55:30 We support JavaScript and a language called Boo, which I think is maybe short for Bamboo. But one caveat, the JavaScript is not really JavaScript. It's more like air quotes JavaScript. We actually call it UnityScript internally. So at one point, maybe years ago, it was JavaScript. It's more like air quotes JavaScript. We actually call it UnityScript internally. At one point, maybe years ago, it was JavaScript. But it was
Starting point is 00:55:51 the way that JavaScript and Unity, or I'll call it UnityScript just to be clear, the way that UnityScript works is it's actually built on top of this bamboo language, this Boo language. So the Boo compiler actually interprets the UnityScript code and then generates
Starting point is 00:56:07 IL code, which we run on the.NET runtime. That's a little bit out there, right? So a couple levels there. But the issue was that as JavaScript evolved, UnityScript did not evolve with it. So UnityScript is
Starting point is 00:56:23 kind of like a snapshot of JavaScript maybe at some point in time. But we do still support it, although we're kind of phasing out support for it now because the C Sharp ecosystem has continued to really evolve and C Sharp as a language has grown. There's some new features of C Sharp, especially in C Sharp 7,
Starting point is 00:56:40 that we want to use in the Unity APIs, and we can't get support for those in UnityScript without significant work from our side. And we think it's better to kind of standardize on one language. So over the next couple of releases of the Unity 3D game engine, we'll be phasing out UnityScript support. We actually have some teams working on tools that'll convert UnityScript code to C Sharp code,
Starting point is 00:57:03 because there's a lot of user code out there that still is using UnityScript, and we want to make sure that those users are supported. So it's still a possibility. Sounds like an impressive undertaking, effectively converting JavaScript to C Sharp. Yeah, I'm not involved in that, but it does sound like a lot of fun.
Starting point is 00:57:21 I think it's going to work, but we have a team working on it now, and the plan is that UnityScript will be phased out, so it's still possible to use right now. But the relationship to IL to CPP is that the bottom line is UnityScript is compiled onto IL, so IL to CPP will convert it then without really caring a whole lot about what the original language was.
Starting point is 00:57:42 Cool. So that's the benefit of.NET and IL in general. You can write multiple languages on top of this same IL infrastructure and kind of share the runtime. Right. And we haven't talked much about the other.NET framework languages, but there's also Fsharp and VB.NET, right? Would they also be able to compile down to IL and run through IL to CPP?
Starting point is 00:58:06 Parts of them can. Those aren't officially supported by Unity. We've done some work with Fsharp kind of internally to make it work, but there's some parts of it that are really difficult to implement and require kind of significant work in the runtime. I know that Mono, for instance, supports
Starting point is 00:58:21 all of that, and they've put a lot of effort into that. So it's something that, since they're not officially supported by Unity, we've not supported an aisle to CPP. But a lot of the code that you'd get out of VB or Fsharp would work. But it's not something that you should try as a developer, I don't think, because unfortunately, if you submit a bug report to Unity,
Starting point is 00:58:42 we'll have to say, well, we don't officially support that, so we probably can't fix it. Okay. Before we let you go, do you want to just tell us a little bit more about Unity and maybe getting into game development? Is this something that an indie developer can pick up and try out for free?
Starting point is 00:58:57 Absolutely, yeah. Absolutely. The whole Unity product is available. You can get all of our platforms that we support for free. I think there's a cap on the yearly revenue or something like that, $100,000. I don't know what it is now. Maybe it's more. But yeah, you can download it and try it, and I really recommend it. So I mentioned one of the things that we try to do is solve hard problems.
Starting point is 00:59:17 Another kind of key tenet for Unity is democratization of game development. The idea is to make it that anybody who wants to make a game can. Now, I really, you know, since working in the games industry for the past few years, I've come to a great respect for game developers because it's not an easy task. I mean, balancing coding, artwork, sound effects,
Starting point is 00:59:37 you know, performance optimization, you know, understanding different devices and architectures, there's really a lot there. Right. And, you know, and then not even counting like backend things like servers understanding different devices and architectures. There's really a lot there. And then not even counting back-end things like servers and analytics and all these things you need to make a successful game. It's pretty amazing how people do it.
Starting point is 00:59:56 But yeah, anyone who wants to get started, Unity3D.com is the website. They can download it and give it a try. Well, and since we're talking to a bunch of C++ developers here, we talked about using UnityScript and C Sharp for effectively writing your Unity game. Can we use C++ to write a game with Unity also? Yeah, it's possible.
Starting point is 01:00:14 The Unity API is not available in C Sharp, so you're going to be restricted in what you can do. You mean not available in C++? Sorry. Thank you. Yes, you're right. I got mixed up. Yes, not available in C++. So the You mean not available in C++? Sorry. Thank you. Yes, you're right. I got mixed up. Yes. Yeah, not available in C++.
Starting point is 01:00:28 So the API is only available in C Sharp. Interesting. So places where you need to interact with Unity, you have to use C Sharp. But, you know, it's not uncommon for games to have significant parts of their code that are native code, even with Unity. Okay.
Starting point is 01:00:39 So if you're looking for, you know, something where you want to write it in native code, you know, that's certainly possible. Now, one of the kind of cool things that we have coming up on the horizon, which I'm not directly involved in, but I've seen it at our conferences and whatnot, is kind of a... What's the best way to describe it?
Starting point is 01:00:59 It's kind of a new idea for thinking about high-performance code in C Sharp. So the idea is to take the garbage collector out of the equation, provide a native like memory management. So I can say I want, you know, arrays and lists and sets of memory, which is contiguous and really take a data oriented design view so that I can, I can, I can set up all my memory the way I want. I don't have to worry about the GC putting it in a different place or moving it or anything like that. I set it up how I want. I can now spread out my computations and my tasks
Starting point is 01:01:30 across many different threads or cores on a machine and do this all from C Sharp. Our goal is to say, we can get as good or better performance than we can with native languages in some respects. So you can do, so that's coming down the line, I think maybe in the next Unity release
Starting point is 01:01:51 or the next one after that. But it'd be something to check out, especially if you're a developer working on, you know, in native code for performance. Okay, you know, it might be a trade-off if you want to take a look at it. Do I get, you know, as good a performance in a managed language?
Starting point is 01:02:04 Maybe I get a little more safety, or do I want to stick with a at. Do I get as good a performance in a managed language? Maybe I get a little more safety or do I want to stick with a native language where I'm closer to the machine, but I may have a little bit more that I have to manage on my own. Okay. Well, thank you so much for your time today, Josh. Where can people find you online? My blog is
Starting point is 01:02:19 joshpeterson.github.io and petersonjm1 on Twitter. And also check out the Unity 3D blog. We've got a lot of content up there for game developers. About two years ago, I did a series about IELTS CPP internals. So if you're interested in seeing how the C++ code gets generated
Starting point is 01:02:37 and some of the things we discussed, it's there. And there's another kind of mini-series that we did about a few optimizations that the IELTS CPP Plus transpiler makes. Now, it doesn't do many, but it does a few things to try to optimize the code based on the knowledge it has. So those might be something to take a look at if you're interested. Cool.
Starting point is 01:02:53 Great. Thanks so much for your time today. Yeah, thanks for joining us. Thank you. I enjoyed it. Thanks so much for listening in 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 you're interested in, or if you have a suggestion for
Starting point is 01:03:08 a topic, I'd love to hear about that too. You can email all your thoughts to feedback at cppcast.com. I'd also appreciate if you like CppCast on Facebook and follow CppCast on Twitter. You can also follow me at Rob W. Irving and Jason at Leftkiss on Twitter. And of course, you can find all that info and the 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.