CppCast - C++ Object Model

Episode Date: December 21, 2017

Rob and Jason are joined by Nicole Mazzuca to talk about the C++ Object Model, and some of the differences between Rust and C++. Nicole is someone who's thought a bit too much about object mod...els and error handling. She started in C, moved to Rust, and then fell into C++ a year ago. She also loves coffee, and latte art. News Meson 0.44.0 is out C++Now 2018 Call for submissions MSVC code optimizer improvements in Visual Studio 2017 version 15.5 and 15.3 Broken warnings theory Nicole Mazzuca @ubsanitizer Nicole Mazzuca's GitHub Links CppCon 2017: Nicole Mazzuca "Values, Objects, and References, oh my: The C++ Object Model, and Why it Matters to You" Sponsors Undo Audible Hosts @robwirving @lefticus

Transcript
Discussion (0)
Starting point is 00:00:00 Episode 131 of CppCast with guest Nicole Mazzucca recorded December 14th, 2017. This episode of CppCast is sponsored by Undo. Debugging C++ is hard, which is why Undo's technology is 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.io to find out how its next-generation debugging technology can help you find and fix your bugs in minutes, not weeks. And by Audible. Get a free audiobook download and a 30-day free trial at audibletrial.com.
Starting point is 00:00:38 Over 180,000 titles to choose from for your iPhone, Android, Kindle, or MP3 player. In this episode, we talk about some Visual Studio updates to help manage warnings. Then we talk to Nicole Mazzucca. Nicole talks to us about for 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 your host, Rob Irving, joined by my co-host, Jason Turner. Jason, how are you doing today? I'm doing okay, Rob. Through the magic of radio here, I guess, this is being recorded one day after the last episode.
Starting point is 00:01:53 Indeed, we're doing time travel again. So I got a new tooth. Nice. Because we did mention that. And I think I'll maybe be a little bit more alert today hopefully that's good but this is we're doing time traveling here not time travel debugging mind you right just time traveling of the episode because i'm heading off to poland to do some training there um on saturday awesome awesome so uh can you tell us what company you're going to? Who are you going to be seeing in Poland?
Starting point is 00:02:28 I don't know. I didn't discuss with them if they want me advertising that or not. But it's a consultancy that's in Wroclaw. And it looks like it'll be a beautiful time of the year. They're expecting some snow and they've got a wonderful Christmas market downtown. I'm hoping to see that. Very nice. That should be fun. know and they've got a wonderful christmas market downtown i'm hoping very nice yes very nice that should be fun uh i also am wishing we could do some real-time traveling right now because i'm very excited for the star wars movie coming out this friday isn't that oh i thought that was
Starting point is 00:02:56 tonight for some reason uh i think yeah the midnight midnight showings yeah i might try to find one of those yeah you've got kids I'm sure they would love to go. Yeah, I'll have to do that. Well, at the top of our episode, I'd like to read a piece of feedback. This week we got an email from Nikolai Zapoklov, and he writes in, Hello, Rob and Jason. Your show is really useful for new developers
Starting point is 00:03:19 to introduce in the context of developing software and C++ especially. Thank you. Could you touch the topic about wrong using design patterns? I heard a lot of developers very often abuse using design patterns. Maybe someone can share his experience about restrictions and using design patterns and when they stop working. We haven't really done any episodes on design patterns. Are you a design patterns guy?
Starting point is 00:03:44 I wouldn't say i'm a design patterns guy i know you i feel like i know almost nothing about them yeah i mean and and i've seen discussions where people say well why doesn't the standard library have templates for the various design patterns that are the most common popular and the responses seem to be something along the lines of uh you know the design pattern should be a guideline not something you try to shoehorn all of your designs into basically right but i don't know i it's actually it's been on my to-do list for literally over a decade to make sure i understand better yeah yes i should probably get to that to-do item at some point.
Starting point is 00:04:25 Yeah, I could definitely see doing an episode about it too. Could we get someone on who is very familiar with multiple design patterns and can speak to, you know, this is good for that, this is not. Do you know who the Gang of Four is? I'm familiar with the book, yeah. Yeah. Well, maybe we should try to get one of those guys on here. Yeah, that'd be good. That book, yeah. Yeah. Well, maybe we should try to get one of those guys on here. Yeah, that'd be good.
Starting point is 00:04:46 That'd be crazy. Yeah. Well, we'd love to hear your thoughts about the show. 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 Nicole Mazzucca. Nicole is someone who's thought a bit too much about object models and error handling she started in c moved to rust and then fell into c++ a year ago she also loves coffee and coffee
Starting point is 00:05:11 and latte art nicole welcome to the show hello what do you think of design patterns nicole uh i have not ever really thought about them to to be quite honest. I thought with that intro of object models, well, but that's object modeling versus object memory object models, right? Right, yeah. It's more like objects have value semantics as opposed to objects are patterns, I guess. Right. Like, the only thing I can even think of that's anything close to a pattern is Sphenae or something. Yeah, that's really not
Starting point is 00:05:52 one of the design patterns, I don't think. Hey, it's very important to design your classes to be Sphenae friendly. Yes. So, do you want to talk about this love of coffee art at all uh i mean it's just i like making latte art it's it's a fun thing to do on coffee and people get happy when i i'm a barista in my everyday life. Right, that's an important note, I think, here, yes. Ah, and, I don't know, people tend to enjoy it when I make latte art,
Starting point is 00:06:29 because latte art's awesome. Some of the pictures I've seen on the internet are, like, nuts. Like, what kind of things do you do? I am not that good. You're not, like, make a Darth Vader? No, I cannot make a Darth Vader. I've not been practicing for 10 or 20 years. I mostly do, like, hearts and, like, leaves and stuff like that.
Starting point is 00:06:49 You know, just basic stuff. Oh, that's cool. Yeah. Okay, well, Nicole, we've got a couple news articles to discuss. Feel free to comment on any of these, and then we'll start talking more about your love of the object model, okay? Okay. Okay. So first the Nissan build system release 0.44.0 is out. Jason,
Starting point is 00:07:12 anything really big to share with this one? You know, I don't know if there's anything of particular stands out, but I think it was just important to mention it because we've had, we've talked about Nissan on here before. We haven't done a dedicated episode yet though i don't believe right i will have to look i don't think we have no i don't think we have we've talked about cmake a whole lot more than we talked about some of the other build systems like nissan did talk about Nissan. There we go. You're right. You're right. Episode 38.
Starting point is 00:07:46 It was a long time ago. With the author of Nissan, yes, which is why I was thinking we should have this up here. But anyhow. Yeah. Okay. Are you involved in build systems at all, Nicole? I've thought a lot about their design.
Starting point is 00:08:05 And me and Izzy Muerte were going to do some work on a build system, and we've kind of started a little bit. A module-friendly build system, perhaps? Yeah. That's something that's really important to me.
Starting point is 00:08:21 I don't think it's going to be in the initial release, but definitely important to look up modules right okay yeah uh next up we got a c++ now 2018 call for submissions yes and this one uh what is the dates on these jason um oh that's terrible that link that i have on there didn't say the exact date And what is the dates on these, Jason? Oh, that's terrible. That link that I have on there doesn't say the exact date. It's March, I believe.
Starting point is 00:08:53 It says submissions due on January 24th. Oh, January 24th. Okay. And decisions get sent out February 26th. Program will go online March 18th. So I have made my submission. You're already in? Okay. Yes.
Starting point is 00:09:04 This year I am attempting to give one talk. That's good. Just one talk. Didn't you send in three last year? Yes. It is my goal to go to this conference and give one talk. We'll see what happens. The risk is you make one submission and it doesn't get accepted, right? Then you have to decide what you're doing.
Starting point is 00:09:26 I think it's a lot better than sending in three submissions, though, and getting two accepted and not being able to handle it. Or getting all three accepted. Hey, I think I've always... Oh, I know, I know. Are you planning to submit anything, either one of you? I don't have any plans right now to submit anything. How about you, Nicole you i don't have any plans right now to submit anything how about you nicole i don't i don't either uh i don't really have anything that i want to say right now i've mostly been using ocamel recently and not c++ so i don't have a lot of opinions
Starting point is 00:09:58 about c++ right now okay okay uh next we got uh two articles from the Visual C++ blog. This first one is code optimizer improvements in Visual Studio 2017 versions 15.5 and 15.3. So it looks like they made a ton of improvements between 2017 and the 2015 update 3. Yes. Yeah. the 2015 update 3. Yes. And I think more important than the fact that Visual Studio now has these optimization features is as a C++ developer,
Starting point is 00:10:36 reading this article to understand what kinds of optimizations the compiler writers are thinking about. And there's some technical stuff in here, lots of assembly examples, how conditional moves can help the code, for example. And then things like CSE, common sub-expression elimination and stuff.
Starting point is 00:10:58 And SSA is mentioned here, static single assignment form, which is also important to understanding how optimizers work. I feel like I have a passing familiarity of these things, but for anyone who's interested, they should read this. Yeah, it's definitely worth scrolling through the article and seeing kind of how the optimizer is working with some of these improvements.
Starting point is 00:11:20 Yeah. The loop unrolling is really interesting in my opinion um how how they do loop unrolling and then like are able to optimize based on the loop unrolling it feels very similar to like the stuff that you can do if you uh inline um yeah so it's just like i don't know i like that it's cool yeah, I like that. It's cool. cache, if you will, by making unrolling everything outweigh the benefit of doing the unrolling, since modern CPUs are really good at jumping and keeping hot code and path in the cache. But this kind of example like they have, where you've got a known size, and they know that they can exactly unroll it to four things, I feel like that has to be a clear win. And then the
Starting point is 00:12:24 optimizations that they can perform after that, like you were saying, is pretty cool. I feel like for real programs, there are a lot of little loops like this, but it would be... I don't know, I'm just thinking about loops with 128 or something like that. And at that point, you're probably unrolling it eight times and then looping, as opposed to unrolling it 128 times,
Starting point is 00:12:55 which that's an insane number and will not keep you in iCache. Right. The partial unrolling that some of them will do. And I've also noticed with this kind of loop, like if there's a known size or something with partial or partial or full unrolling, and these were like, you're working the,
Starting point is 00:13:13 this, the unrolling gives the vectorizer the chance to work and potentially use SSE instructions also. Yeah, exactly. Okay. And then the other article we have from the visual c++ blog is the broken warnings theory and the the main thing that they're announcing here is these new external
Starting point is 00:13:34 compiler switch groups which will allow you to basically disable or change the warning level for external headers and this is something that i think will be really useful for getting a build with clean compiling without warnings or with all your warnings turned on, not having to worry about all these external headers. Did you notice in the statistics at the top of this article, they say 27 respondents to their survey, 27%, excuse me, of the respondents to their survey, compile Visual C++ applications with dash W all. Yeah.
Starting point is 00:14:11 And I find this fascinating. I mean, that's what I do. Like, I do dash W all, and then I just turn off specific warnings. In Visual Studio? In Visual Studio and in Clang, I use W everything and turn off specific warnings. I Visual Studio? In Visual Studio and in Clang, I use W everything and turn off specific warnings. I have found, okay,
Starting point is 00:14:29 so there's a philosophical difference here, right? Because Clang and GCC exclude themselves from warning messages. Excuse me, the standard library excludes itself from warnings. It's treated as a system header by default. In Visual Studio, it does not. The standard library does not exclude itself from warnings by default.
Starting point is 00:14:50 So when you turn on WALL, if you include even the simplest header in Visual Studio, you get a bunch of warnings and you have to selectively disable some of them. But I think this is actually better because Visual Studio is clean up to W4 and Clang is not. And GCC is not. The standard library isn't because they exclude themselves from this. Anyhow, I like the way the Visual Studio team does it, but I also find it kind of handy to have these new tools that Rob was pointing out. Yeah.
Starting point is 00:15:23 Yeah. Go ahead. So one thing that I'm noticing is like one, modules kind of makes this obsolete and that makes me happy. What was the other thing? I was going to say something and I can't remember. Oh, it was really interesting
Starting point is 00:15:41 like talking about this article on the Slack because like how different developers have relationships with warnings. When I'm writing code, I will correct all of the errors and warnings before doing anything. But I was talking to this person who, as they're refactoring, they want to debug without fixing all the warnings. That was just a really interesting, like difference in, um,
Starting point is 00:16:08 developer behavior. Yeah. Yeah. Yeah. Hmm. Yeah. I feel like fixing the warnings first is probably going to make my debugging task easier because there's probably a good reason those warnings were there.
Starting point is 00:16:19 I mean, on the other hand, you have like, uh, unused variable warnings and stuff like that, which is what they were referring to. It's, like, it's an annoying thing. Yeah, unused variables are significantly less likely to be a warning that's going to cause a bug.
Starting point is 00:16:35 Yeah. Yeah. Okay, well, Nicole, at CBBCon this year, you gave a talk on the C++ object model. Can you tell us a little bit about the talk and how it went? Yeah, so it was my first talk ever, and it was very nerve-wracking, and it was a ton of fun. I feel like I could have prepared better, but otherwise it was a good talk. And I just kind of...
Starting point is 00:17:01 It was mostly about where in the C++ standard we needed to fix some stuff or work on some wording. The wording around const and reference member variables inside of classes is a bit weird. It's like if you have a const reference member, you basically can never put a different thing in that space. Right. So if you have a vector, for example, and you have a type
Starting point is 00:17:38 in the vector with a const reference member, and you push back, and then you pop back, and then you push back again, that's like undefined behavior um like like the standard libraries are committing undefined behavior by doing that because there's no way to actually do this correctly basically uh let's like dig into that like yeah so what is this push back pop push, pushback, pop, pushback, whatever? How does that invoke the undefined behavior? So basically what you're doing is you're constructing an object into storage, right?
Starting point is 00:18:15 Like the storage does not mean anything, but you're putting an object. It's uninitialized. It's uninitialized storage. You're putting an object in there. Right. uninitialized it's uninitialized storage you're putting an object in there right so the pointer that the vector uses to like point to the array now points to an object okay you pop back and it deletes the thing and you push back again and because it had a const or reference member, the new object, the pointer does not point to the new object. It just points to memory where the new object is located.
Starting point is 00:18:52 Okay. And this is so that, obviously, implementations can optimize out, like, if you have a const or reference member, you can check it once and then you never have to check it again, basically. Right. But because of this issue with vector and issues with placement new and stuff, no implementation actually does this yet. They do do it for VTables.
Starting point is 00:19:16 Right. Which is less of a big deal, because if you're changing your VTable, you deserve to get bitten. But that's what standard Launder was introduced to do. Unfortunately, you basically have to use std launder at every single access point, and it's a huge pain, and
Starting point is 00:19:35 it also doesn't work. For some reason, I can't remember exactly why. And it also only works for actual pointer types, as opposed to custom pointer types as well. Okay. So there is an object at a particular memory location. It has a const value, a const member.
Starting point is 00:19:54 The compiler is allowed to optimize around that. Yep. And we've just replaced that object with a new object. Yep. And now the next time we go to access that const member we are potentially invoking undefined behavior because the compiler was allowed to optimize around the const basically yeah and there's like no way to get around it except for laundering the pointers except for laundering the pointers but then you have to use the return result of launder
Starting point is 00:20:22 and again it doesn't work with uh custom pointers and stuff right and at that point you have to use the return result of launder. And again, it doesn't work with custom pointers and stuff. Right. And at that point, you have significantly crippled the optimizer, probably if you're laundering every single access to every single object in a vector, for example. I mean, I don't think it'd be, like, except for Vtable optimization, it shouldn't be a major thing.
Starting point is 00:20:47 Okay. And for vector, you don't really have issues with Vtables because you can't really have multiple dynamic type objects. No, you have Vtable-like things if you have a vector of variance, but they are not exactly the same thing, yeah. Yeah. So it's, like, for that specific use case it's not like a big deal because the compilers don't do the optimization anyways because it would break code um and it would break standard library code that's supposed to work Um, but like, yeah, so it's kind of a CF.
Starting point is 00:21:26 I'm kind of, um, I'm a little like, since I don't know the details of where exactly the compilers are to optimize, like I've tried to familiarize myself with them, but some of these things are like, you have to know like six different parts of the standard, right? Yeah. Once you have called the destructor on an object or reused its memory location, then the lifetime of the first object has officially ended. I know that rule. So at what point, since you've ended the lifetime of the first thing, and then you've replaced that, it seems like what is the compiler supposed to do there
Starting point is 00:22:06 exactly so basically yeah you end the lifetime of the old object and even this is some really arcane stuff yeah our listeners like it when we get more technical
Starting point is 00:22:22 that's good so let's say you have a pointer that points Our listeners like it when we get more technical. That's good. So let's say you have a pointer that points to an object. Yes. Now, you don't delete it. You placement destroy. What is that? You can just manually call the destructor.
Starting point is 00:22:42 Manually call the destructor. I don't actually know what that's called, but I'm going to call it manually calling the destructor. Manually call the destructor on this object that's at this certain memory address. The pointer now points to nothing, right?
Starting point is 00:22:57 Well, it points to an invalid object, I guess, technically at this point. Yeah, basically. If you then placement new a new object into that storage, the pointer points to the new object if and only if the new object is the same type as the old object and the type of the objects that are the same because otherwise it wouldn't point to the new object or the type of the objects that are the same, because otherwise it wouldn't point to the new object.
Starting point is 00:23:28 Um, because you know, TBA and stuff. Um, and there are no const or reference members. Oh, that kind of makes sense. And there are no const or reference members.
Starting point is 00:23:38 Yeah. Yeah. So that's handy or reference member. Then the old pointer that pointed to the old object does not continue to point to the new object. So there is actual specific wording around that. Yes. I wish I did not know that now.
Starting point is 00:23:55 If the table changes that it's the same wording, right? Um, so I don't, I don't believe that it's actually, like, you, I think you can access non-constant non-reference members, but it's accessing the const or reference member. Like, it, the, the sub-object inside the object that's const or a reference, even though it's not actually an object if it's a reference, not a reference. Right. Uh, will, it, like, doesn't point to the new one. It points to invalid because you destroyed the... It's crazy and it's just written
Starting point is 00:24:30 so that your optimizer can trust that constant reference members never change, but the issue is they do. That's crazy. I was not aware of that. There's a lot of crazy stuff in the c++ standard
Starting point is 00:24:47 tronced pr values they're great just well so i enter go ahead go ahead jason no i was going to say i interrupted you in the middle of what you were saying to dig into this i was just wondering where you were going to go next but if rob has a question along these lines first i was just going to say to to roll back a bit, I kind of want to know where you got so interested in the C++ object model in the first place. I mean, we've had listeners who are really interested in compilers, and they go and build their own compiler. I just kind of want to know what the history was there.
Starting point is 00:25:17 So the history basically starts with Rust. I was a Rust programmer for a really long time. I'm not really anymore, but like I was for a long time. And one of the things that I started kind of getting into like really unsafe code in Rust. Like that tweet you recently sent out? Yeah. Okay, no one liked the original tweet where I printed my name using the fact that Linux has read-only memory as executable. But everyone liked my tweet that it was like replying to somebody. Oh, yeah. at you yes it did that yeah okay so everyone liked my tweet about technically everything is executing memory and i thought that was kind of it made me sad because i'm really proud of that snippet i guess and unfortunately we've derailed again but for the sake of our listeners you uh wrote a statement of rust and see if i can get this right and you can correct me if I'm wrong where you put some
Starting point is 00:26:27 effectively hand compiled code in and then jumped into this code and executed it which is the kind of thing that you would say Rust shouldn't be allowed to do because Rust is very safety conscious but there's an unsafe keyword so you can do whatever the heck you want
Starting point is 00:26:43 including execute undefined behavior okay that's that's kind of like so the thing about rust is you the idea is that you can't have undefined behavior if you don't have the unsafe keyword and the unsafe keyword allows you to do undefined behavior that's not true because lovm is bad but no lvm is awesome but it does do some stuff that like you cannot work around like for example a into float cast and float to in cast uh are undefined behavior if they're outside the bounds um and you cannot do anything about it. In Rust. In Rust. But in LLVM semantics. So there's no like, just do whatever the hardware does.
Starting point is 00:27:31 Right. Like the optimizer will always assume that an into float or float to int cast is undefined behavior if it goes out of bounds. Which means that you can like do whatever the heck you want in Rust if you have an out of bounds float to int
Starting point is 00:27:42 or into float cast. Okay. And then also, like, infinite loops, they're optimizable in C++. They're not optimizable in C and Rust. So, or, like, infinite loops without side effects.
Starting point is 00:27:58 Right. But LLVM just assumes they're optimizable, which is bad because it breaks C and Rust. Interesting. I think they're fixingizable, which is bad because it breaks C and Rust. Oh, interesting. I think they're fixing that with an intrinsic... But anyways, I got into unsafe code and Rust. And one of the things that's a big part of unsafe code is this function in the standard library called transmute,
Starting point is 00:28:24 which is basically C++. You'd call it bit cast. Like it's take the bits of one object, take the bits of one object, mem copy them into another, an object of a different type, basically. And,
Starting point is 00:28:41 and Rust like checks that they're the same size and it, it's incredibly unsafe and people use it for pointer casts and it's really, really, really not good. Um, this, it's, it's a big thing, anyways. Um, but, like, as part of the Transmute, you have to be interested in, like, object models and how all that works together. So, I got interested in the rest of object model and then as i kind of fell into c++ i got really interested in references because references are really cool like i feel like references are probably c++ like one of c++'s top features interesting unfortunately not super ergonomic and there are some mistakes that were made in the design of references um in my opinion um like for example uh forwarding references i believe are i would i would argue
Starting point is 00:29:32 they're a design mistake um but basically it's like a really it's um they're a really cool feature because they're c++ is the only language that I know of that allows you to have a value which is an object. That kind of makes sense. The reference itself, you're saying. The reference itself is a value which is an object. You are able to pass objects around as if they were just normal values. And you can pass values around as well. As opposed to something like OCaml,
Starting point is 00:30:09 where everything is a reference. In C++, you have both reference and value semantics, which is really, really cool. And I'm not being super awesome, like talking about, well, not talking about this super well, but it's really cool cool is the point. And it fascinated me.
Starting point is 00:30:29 And then I got into the object model of C++ through that, kind of. And, like, reading the standard a lot, because the standard's really fun to read. So I believe you are officially the only guest we've ever had who would actually say the standard is really fun to read. And we've had people on who work on the standard yes it's like it's it's legal language it's really it's really enjoyable to like suss out the actual intended meaning and like i don't i don't know it's fun it's fun in my classes i try to do a little bit of like uh learning how to read the standard for when you need it.
Starting point is 00:31:06 Not like reading the standard for fun and pleasure or something. I don't think of it as bedtime reading. I mean, clearly you've never read the... Michael Case did the Beat. Oh. That is actually in the C++ standard and I love it so much that was the secret
Starting point is 00:31:32 lightning talk from meeting C++ 2016 I think so yeah I've like literally shown that to people who are not programmers and been like look C++ programmers are awesome. And you have fun stuff like the.zombie
Starting point is 00:31:52 namespace in the standard, which is for things that are deprecated, I think. The standard is a barrel of laughs. Let's just say that. Alright, everyone, you've heard it from Nicole. You should have fun reading the standard after this episode.
Starting point is 00:32:10 Yeah. And also reading old standards is really fun because you're like, what the heck were they thinking? Like, there is a clause in the C++03 standard that basically says if you bind a reference to a temporary, temporary or an object of the same type, the compiler is allowed to emit infinite copies.
Starting point is 00:32:33 Allowed to emit infinite copies. Yeah. There's an implementer's note that says, note, you may want to stop because otherwise you're, it would be useless or it was like, or no, no, no. You might want to stop at some point because otherwise you'll have infinite recursion.
Starting point is 00:32:51 This seems like, um, it must've been around the wording that I think most people aren't maybe necessarily familiar with. And I honestly need to spend a little bit more time with, but how you can extend the lifetime of a, of an object returned from a function by assigning it to a const reference. It's not actually related to that.
Starting point is 00:33:09 It's not related to that. Okay. You know, it's like there's... So basically, there's a thing which says there's two things you can do with a temporary to bind it to a const reference. You can copy it into a new temporary of the the reference type or you can bind the temporary object to the reference okay but the issue is it doesn't say like you only have to you can only copy once it just has those two things next to each other okay so it says like you put the object into or you put you put the temporary object into a new object and bind the const reference to it.
Starting point is 00:33:49 And in order to bind a const reference, you do that, or you just bind the reference to the temporary. And it doesn't say you can only do this copy once. It has an implementer's note. You might want to stop at some point because it will infinite recursion otherwise all right there's a lot of really silly wording
Starting point is 00:34:10 i wanted to interrupt this discussion for just a moment to bring you a word from our sponsors you have an extensive test suite right you're using tdd continuous integration and other best practices but do all of 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's live recorder technology allows you to easily fix the bugs that don't otherwise get fixed capture recordings of failing tests in your test suites and debug them offline so that you can collaborate with your development team and customers get your software out of development and into production much more quickly, and be confident that it is of higher quality.
Starting point is 00:34:49 Visit undo.io to see how they 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 as someone who studies the object model and reads the standard, what do you think is something the average C++ developer should know about the C++ object model that they probably don't already? Honestly, there's not too much that you need to worry about. It mostly just does the right thing like like except for some major like some issues with constant reference members um and this isn't really related to the object model but constant pr values as well like those three things are really the only major things that you kind of need to worry about um so constant reference members basically the lesson to take home is don't ever use them. Just use pointer
Starting point is 00:35:46 and mutable or not. Non-const members. Or like std reference member or something. Well, const members are very difficult to work with effectively. Right. So just don't worry about that part of the standard. Just don't use const or reference members
Starting point is 00:36:01 is basically the idea. And then on const br values basically just never return a const object from a function because the c++ standard does some weird stuff with it yeah it's generally considered best practice that that never does what you want it to actually accomplish so stop doing it right. Right. Oh, and always put ampersand on your operator equals. Ref qualify your operator equals, so you can do as the ints do and not take L values. Operator ref.
Starting point is 00:36:36 You say always ref qualify your operator equals. Operator equals. Specifically the copy operator or the move assignment? Anything that is an operator equals. Specifically the copy operator or the move operator or move assignment? Anything that is an operator equals. Just because then you can't say if your class is foo, foo open print close print equals other foo. Right.
Starting point is 00:37:01 So you can't assign to a temporary effectively. Yeah, basically. Okay, so if I were to say I want the default implementation that the compiler is going to provide for me, for my assignment operator, would you recommend that you do the ref qualified equals default? Yeah. Does that prevent the compiler from creating the rvalue ref qualified one, or do I need to explicitly delete that one? You know, I haven't actually checked. That's an interesting question. I'm going to check on the compiler explorer,
Starting point is 00:37:33 because that is curious to me. I'm guessing it would prevent it from being created, or it will... I do, too? Because it can't create the non-R-value reference-qualified one because you can't have both reference-qualified and non-reference-qualified versions that overload each other. And by default, it's not going to make the R-value-qualified one. Yeah.
Starting point is 00:38:01 So we did some investigation that Rob has edited out, and it's not entirely clear what the compiler is doing at this point, and it's going to take some more investigation, and hopefully Nicole will write up an article on this or something that we can link to later. Sure, definitely do that. I just volunteered you for that. Okay, good.
Starting point is 00:38:20 But yeah, basically, as long as you avoid returning const objects from functions like const foo bar open print close print as long as you avoid const and reference members and as long as you no those are the two big things
Starting point is 00:38:37 that like the C++ standard will do what you expect it to there are some like C rules that you cannot follow like the whole union thing like you can bitcast it will do what you expect it to. There are some C rules that you cannot follow, like the whole union thing. You can bitcast it from unions in C, but you can't in C++.
Starting point is 00:38:52 But other than some stuff like that, it's mostly just, it does what you expect it to. Honestly, Ximity has done a really great job at C++ 11 and up models. They are absolutely fantastic
Starting point is 00:39:07 as far as object models and all that goes, in my humble opinion. Yeah, we've had other guests say that the C++11 object model literally changed their business because it made more things possible. Memory model and object model, yeah.
Starting point is 00:39:23 The memory model's great. yeah yeah the uh the memory model is great the reference model is great the object like c++ 11 turned like a pretty crappy language in c++ 03 into like a freaking fantastic language it's it's like the standards committee does not get enough uh recognition for how much work they've done. So as someone who used to be more involved with the Rust community, what would you say that C++ could maybe learn from Rust? More static analysis is, I think, always a good thing. I feel like something like Sal,
Starting point is 00:40:03 Microsoft Sal, which are those really weird C things that you write in, like out param and stuff in the Microsoft. I don't think either one of us is talking. Yeah, we're not sure. So in Windows code, basically, there's a lot of like attributes. Okay. That you like write around stuff like for example this size t parameter is the length of this other pointer parameter okay so you can do like good um annotation or not annotation static analysis around that right um and you're losing a lot less information as you
Starting point is 00:40:41 do function calls and you can specify in parameter, out parameter, in out parameter, or whatever. Exactly. And I think that it would be good to, like, it would be interesting to add, like, lifetime annotations in that kind of way. Because I think lifetimes are a really big deal, and they're really cool. The other things that I think C++ could learn from REST is more safety by default. Like, one of the things that C++ does really well is fast by default, but for most things,
Starting point is 00:41:12 you don't actually need it to be that fast. Like, I think that ftrapv, like, if you overflow an integer, you trap, as opposed to undefined behavior, would be, like, a really good default to have for compilers. Interesting. Um,
Starting point is 00:41:29 and in general stuff like, like, uh, like operator, open bracket, close bracket for vector. It should trap. If you go,
Starting point is 00:41:37 if you like do a buffer, buffer overflow, because that's like a safety issue at that point. And it's like, it will screw up stuff um and i think that c++ people are a little bit too obsessed with speed over safety um and specifically making the easiest path the unsafe speedy one right like it would be totally fine to have like operator open bracket close bracket on vector check for overflow and trap if it overflowed and then just have like an unsafe get or unchecked
Starting point is 00:42:14 get or something as opposed to the opposite of what we have right now where the index operator is unsafe but then we have dot hat if you want it to do a check. Yeah, and also there's a lot of exception throwing in the C++ set. .hat will throw an exception if you do it. You'd prefer just a crash. I would prefer just a crash because you're saying this is a bug, but it's not going to fuck up the rest of your code. Or it's not going to screw up your, sorry for saying, it's not going to screw up your, uh,
Starting point is 00:42:46 uh, your, uh, your security or whatever. It's just going to crash. Right. You have gotten to a point where you are, your,
Starting point is 00:42:56 your business logic is incorrect and we are going to crash instead of letting you continue with that. Interesting. So how do you feel about the, uh, or if you spend any time at all looking at like the checked integer, uh, library kinds of things that do some of the, what you're talking about, but you have to, well, I guess you already said that you would prefer that the easy path was the safer path as opposed to the way around. But I like unsigned overflow is like, why is that? Why can't I have trapping unsigned overflow? And like undefined behavior unsigned overflow that I really dislike that about, like the fact that unsigned is overflowable is weird to me.
Starting point is 00:43:38 That is an old history where that was actually the desired behavior and some 16 bit things and eight bit things back in the day. Yeah, I know. And it also frustrates me as like a modern developer. Right. Cause like, I can't say, you know,
Starting point is 00:43:58 unsigned is trapping on overflow because some other library might depend on it overflowing. And it's just a big crock of annoyance. Right. But yeah, I feel like more checks are a big deal. Also, Rust allows you to do really, really unsafe things behind the unsafe keyword. Like, you could just get the pointer and the size out of a vector,
Starting point is 00:44:23 or pointer size capacity out of a vector, and then recreate them. Okay. And I've wanted that a lot in C++, where I'm, like, say, writing a span type that's owning, and I want to take the memory from a vector, or, like, put the memory back into a vector.
Starting point is 00:44:44 Right. It would be useful to have these unsafe utility methods. Okay. That's interesting to hear that you want some of the unsafe features of Rust brought into C++, but you want the safe features of... you also want the safe features
Starting point is 00:45:00 of Rust, I guess, brought into C++. Yeah. C++ is kind of in the middle in between rust so you have like safe rust and unsafe rust c++ is like safer than unsafe rust but more unsafe than safe rust and i want it to kind of spread out okay like as safe as safe rust and as unsafe as unsafe rust interesting because rust lets you do some insane insane things so you're a barista you read the C++ standard for fun
Starting point is 00:45:34 and you've started with rust you said you're working on OCaml largely now yeah I'm building a compiler for a language that I'm designing and i got fed up with rust so i'm now writing it in this recent taxing of a camel called reason ml done by facebook which i really like um i didn't know that facebook had been involved in the okamal world at all yeah actually like 50% of Facebook Messenger is written in this re-syntaxing of OCaml
Starting point is 00:46:09 called ReasonML. And ReasonML is just basically OCaml, but with kind of more JavaScript-y syntax. Okay. Which is much nicer to my eyes, because I really dislike... There are a lot of issues with OCaml syntax that I'm not going to go into,
Starting point is 00:46:23 but ReasonML kind of fixes most of them, if not all of them. And JavaScript syntax is actually kind of pretty. Kind of. I like braces and semicolons. What can I say? So what's next, though? I mean, pursuing a language, writing your own language is a hard thing. And I'm just trying to remember, I think it was when we had Strewstrip on,
Starting point is 00:46:45 that he has said something along the lines of, don't ever create your own language because either it'll be successful and you'll be stuck doing it for the rest of your life or it'll fail. Something along those lines. Something along those lines. I mean, so if it fails, I got a lot of knowledge. Right. And I can yell at the C++ community to add stuff.
Starting point is 00:47:06 And if it doesn't fail, then yay, I can write stuff in a language that I like, that has linear types, and is similar to ML, or is like ML, but with C++ level performance. That's great to me.
Starting point is 00:47:23 And has destructors and all that, because every language should have destructors. Destructors are amazing. Yeah, I thought it was very interesting when you said that references are the main feature of C++ when, generally speaking, the answer everyone gives is destructors. So the main features of C++, in my opinion,
Starting point is 00:47:38 are destructors, references, from a programming language design perspective not from like a using c++ design right um references are really cool and i don't know any other language that really does them like c++ does i think that's sad um it has really cool the destructors obviously and the idea of value semantics is really cool if not executed super well copy by default is a really bad default
Starting point is 00:48:14 and it's unfortunate that that's the way that C++ went it makes sense that that's the way that C++ went because of the early days but in my opinion it would have been better to do kind of like an affine type system similar to Rust where like
Starting point is 00:48:31 it's moved by default and you just like yeah go ahead and then like you don't call the destructor on a move from object okay right like the compiler does that as opposed to the program right so i'm just curious what's next though i mean you're working on this programming language do you have any plans to go into programming full-time or yeah well so uh i'm i finished my associate's degree and i'm gonna go do a master's at not about masters a bachelor's at uh
Starting point is 00:49:03 western washington university that's great in the north of washington computer science Master's at, not a master's, a bachelor's at Western Washington University. That's great. In the north of Washington. Computer science? Math. Math, okay. Yeah, because math is, computer science, if you're not going to, like, a very few specific schools, is not, in my experience, a very well-taught field.
Starting point is 00:49:22 It's like, it's very it's very, um, inconsistent. Okay. Right. Uh, I mean, it's been a while since I've been in university, 17 years since I graduated. My computer science program was highly theoretical with enough math that if I had taken one extra math class, I would have gotten a minor in math. But due to other reasons, I didn't actually end up, I started down that road, didn't manage to complete it.
Starting point is 00:49:51 So I did not get a minor in math, but yeah. And I, I know that as some, like, I'm super interested in like the theoretical stuff and I don't want to do a lot of the programming stuff. Cause like I've done a lot of that.
Starting point is 00:50:03 I've programmed for like 10 years. I've programmed for 10 years. It's fine. I need the practice of object-oriented programming. Right. Okay. Was there anything else you wanted to share? Where can people find you online?
Starting point is 00:50:20 Do you have a blog, Twitter? I have a Twitter. I do have a blog, but i haven't updated it in like two years or something uh the last the last update that i have on it is like my my so there there's a style guide in rust that was terrible and like had a lot of issues. And the default formatting tool did that style that was really not very good. And so I wrote a competing style guide and got myself on the style team
Starting point is 00:50:53 and now, in my opinion, the Rust style is fairly good. It's better than it was. Match statements, the variant switching statement, they still double indent, which annoys me. But other than that, it's really good. Okay.
Starting point is 00:51:11 I kind of wanted to talk about Mason a little bit, actually. Sure. Because one of the things is, like, the thing, the issue that I have with Mason is, like, this is the best that the C++ community can come up with. It's kind of depressing. I was trying to run Nissan the other day and try it out, and it's incredibly unintuitive. And I feel like C++ needs to get something like Cargo or OCaml's JBuilder that just makes it easy and you don't have to worry about it too much. And it just does the defaults well.
Starting point is 00:51:54 The problem is C++ has so many more compilers and toolchains and everything to try to work with, right? I mean, it does, but like as long... So one of the things that I have an issue with with like modern C++ build systems, which are not all that modern really, is they don't enforce a directory layout. Right.
Starting point is 00:52:18 Which means that you have to put all the directory layout information into the build file. So like, for example, you have to put all the directory layout information into the build file. So, like, for example, you have to, apparently in Mison, you have to say that your include directories are in include. Like, that doesn't seem like a, like, you should just have a single build layout, and, like, that's fine. And, like, you can do, like, a toml file. And I feel like C++ needs to make that shift at some point soon.
Starting point is 00:52:49 Because it's putting off new programmers to C++. If somebody wants to pick up Rust, they install a compiler with RustUp. Oh, and the compiler installation is also really bad. But they install a compiler with Rust up, and it installs Cargo and everything as well. And then you do Cargo new project name, or Cargo new minus minus bin project name, and you're done.
Starting point is 00:53:17 You have a project. All you have to do is start editing Rust code. Whereas with C++, you have to do all of this setup. And to build Mison, and Mison looks like one of the better options out there, if not, like one of the best, you still have to use like Ninja and like all this confusing stuff that is like incredibly weird to like a new programmer. Yeah. You know, so in your hypothetical build system that you've thought about but haven't implemented yet would you enforce
Starting point is 00:53:48 a specific like file layout for the project yes okay like hands down like you'd have a source directory and include directory and in your source directory you'd have like the module files and also the C++ files like that
Starting point is 00:54:03 just definitely needs to happen, in my opinion, is an actually enforced directory layout. And old projects won't be able to go over to it, unfortunately, easily. But it's not a big deal as long as you can interface with old build systems. The thing about ocaml um the new user experience isn't great either especially on windows but the
Starting point is 00:54:33 build system is pretty simple like jbuild is really simple um uh it's not great but it's it's pretty simple but the thing is like this new build system can also interface with all of the old build systems. Okay. And so you don't have to worry about having an old build system with a new build system. You just have a package, and then you can interface with that package. Interesting. Yeah. And I think that C++ could do something similar.
Starting point is 00:55:02 Right. It's definitely something we definitely need improvement in the C++ community. Yeah. The big issue is new users. People are getting turned off C++, and it really sucks, because C++ is a really good language. And it just has a terrible build story, and people don't use C++ because of it.
Starting point is 00:55:27 Okay, well it's been great having you on the show today, Nicole. Yeah. It's been fun. Yeah. Thanks for coming. 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 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
Starting point is 00:56:00 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.