Text broadcast of CppCast 285: Clang Power Tools and C++ myths
- 12 different ways to filter containers in Modern C++
- More_concepts library
- Blizzard Diablo IV debugs Linux core dumps from Visual Studio
- Next steps for Clang Power Tools
- C++ myth busting with Victor and Jason
Episode 285 CppCast was recorded on February 3rd, 2020. Hosts Rob Irving and Jason Turner are joined by Victor Ciura. They first talk about different ways to filter a C++ container and a blog post on the Visual C++ blog from the Diablo 4 development team. They then talk to Victor about the Clang Power Tools plugin for Visual Studio which has recently been made free for both open source and commercial use. They also talk about C++ myths.
This episode of CppCast is sponsored by Visual Assist, the well-known productivity extensions for Visual Studio. Visual Assist speeds up development with features like smart navigation, code inspection, and suggestions, powerful refactoring commands, and a whole lot more – even spellchecking in comments. Start your free trial at wholetomato.com.
Welcome to episode 285 of CppCast. Joining us today is Victor Ciura. Victor is a Principal Engineer at CAPHYON, Technical Lead on the Advanced Installer team and a Microsoft MVP. He's a regular guest at the Computer Science Department of his alma mater, University of Craiova, where he gives student lectures and workshops on using C++ STL Algorithms.
Since 2005, he's been designing, implementing several core components and libraries of Advanced Installer. Currently spends most of his time working with his team on improving and extending the repackaging and virtualization technologies in Advanced Installer IDE, helping clients migrate their traditional desktop apps to the modern Windows application format: MSIX.
One of his hobbies is tidying up and modernizing the aging codebase of Advanced Installer and has been known to build tools that help this process, including Clang Power Tools. Victor, welcome back to the show.
Victor Ciura: Hi, thanks for having me back. It's nice to be back after almost three years now.
12 different ways to filter containers in Modern C++
Rob: Victor, we got a couple of news articles to discuss, feel free to comment on any of these. Then we'll start talking about C++ myths and about Clang Power Tools too. Sound good?
Victor Ciura: Cool.
Rob: This first one we have is a post on C++ Stories and this is 12 Different Ways to Filter Containers in Modern C++. I thought this was a good post, kind of showing how much simpler some of this filtering code can look, if you're able to use C++ 20 ranges or concepts.
Victor Ciura: I enjoyed this article by Bartek. But I was scrolling through the evolution of the filtering mechanism presented there and I was getting right to the end, where he got into parallel algorithms, and it was like a cliffhanger. That's an interesting bit they'll follow up on. He promised a follow-up post on that. I can't wait to see it.
Rob: And this example of doing a filter to copy from one container to another, using a parallel algorithm, I'm pretty sure the only thing you can parallelize there is the actual copy of the object.
Victor Ciura: You can split the work if you're just talking about filtering here and you can do chunks and filter independently too.
Rob: But then you would have to create...
Victor Ciura: ...the merged version, yeah.
Rob: And then merge them.
Victor Ciura: But in a more functional style – returning a copy that contains the filtered-out elements. The idea of this article was leveraging more composition and doing it in a more functional fashion. I see his angle here.
Rob: Next thing we have is a GitHub library, and this is More_concepts. Jason, you tell us about it.
Jason: It's just a library of concepts for C++ 20. Most of them are around containers, random access containers, sized containers, clearable container. It could be handy. I just like seeing people starting to adopt C++ 20 stuff, personally.
Rob: I didn't realize that this type of container-based concepts was missing from the built-in ones we're getting from the STL.
Jason: We're not getting many concepts from the C++ 20 STL, right, relatively speaking.
Victor Ciura: Even in a Bartek's article, he played around with the concept of having a push_back on the container. They are tying together nicely. I'm split regarding this kind of approach in providing a plethora of supplemental concepts for the STL.
We must strike a balance between utility and being overwhelmed or producing too many special purpose concepts that aren't usable in many contexts.
If I remember Bartek was worried about people inventing concepts left and right just to cover and providing nicer API level checks and nicer error messages.
Jason: And I have the problem of the compiler I need to do work on. It doesn't have good concepts support yet. I can't really apply concepts in my real-world work yet.
Victor Ciura: Me neither. Just experiments.
Blizzard Diablo IV debugs Linux core dumps from Visual Studio
Rob: The last thing we have is a post from the Microsoft Visual C++ blog and this is "Blizzard Diablo IV debugs Linux core dumps from Visual Studio".
It's amazing that you're able to do this now in Visual Studio. If you're not used to dipping into a Linux environment and using GDB to debug a core dump, because you do most of the development in Visual Studio, like the Blizzard team is saying they do, then being able to do this in Visual Studio will be a huge timesaving and that's what this article is all about.
I wanted to point out that the article mentions Parallel Stacks, and this is something that I only found out about myself, like a year or two ago. And any Visual Studio user who doesn't know about Parallel Stacks should go and check it out. Anytime you do a Break All or you're debugging something like a core dump, you can look at your list of threads, a textual list and try to pick the right call stack where something may have gone wrong. But the alternative is to use Parallel Stacks, which gives you kind of like a graphical view of all your threads and each one's call stack. The nice thing you can do with that - ignore all the smaller graphs, because they're just waiting for work. Look for the big call stack graphs because that's where probably something is going wrong.
Victor Ciura: The default view is a very slim Combo box, just the entry point name. It's an old feature, but lesser known.
Rob: Anything else you wanted to point out with this article?
Victor Ciura: On a related note of lesser known, but older Vision Studio features, I was just about to say that very few people know that you can customize the debugger experience in Vision Studio and define with the help of some XML files and predefined schema. You can define the layout of your custom objects and how you want them to be surfaced in the debugger when you hit the break point, what exactly from the innards of your complicated data structure, how exactly do you want to present that easily in the debugger view in the Watch Window or something like that. The Visual Studio team did that for the STL types. And you can do that the same thing for your types. Bartek has a very nice tutorial. Very few people know about this feature.
Rob: I think we mentioned it before, but I'll put a link in the show notes.
Next steps for Clang Power Tools
Rob: Well, Victor, can we start off by the update on Clang Power Tools since that's why we had you on the last time on the show?
Victor Ciura: Back in 2017 I was excited coming on CppCast and talking about the brand-new Clang Power Tools. We've been working hard on adding tons of features and functionality to the suite of tool and in 2019 we set out to work full-time on this because it started like open "hobbyists" kind of thing that we developed to consume and leverage internally. It soon gained a lot of traction in the community and people started coming up with ideas, and bug reports, and suggestions, and feedback, a few patches. But we did most of the work ourselves. We were victims of our own success, and we were overwhelmed by the work that we had to do. In 2019 we hired a full-time team to work on this, and we worked ever since to deliver on those promises and all those suggestions and feature requests and reports.
We announced a separate standalone tool for Clang Format Editor and Clang Format Configuration. So many people have a hard time figuring out the Clang Format or settings suite to match their code base. Recently we shipped this separate update that's not tied to Visual Studio, so it can be used independently.
The biggest change – it's completely free now. We hope that this will bring back more people to use the tool both at work and in personal hobby projects. They can leverage the power of the LLVM framework and the power of Clang-Tidy and find stuff in the code base, not worrying about the tooling and infrastructure and just worry about fixing the bugs and the problems they find in their code base.
Rob: Do you still have a full-time team devoted to working?
Victor Ciura: We do, because we're using the tool internally. We will keep pushing and doing the backlog stuff that we have and improving it. The biggest win from this experience from 2017 up to now – we've raised awareness in the community of Windows developers that were not accustomed to leveraging these kinds of tools like Clang LLVM tools in general and Clang-Tidy. These things became mainstream for Windows developers as well.
The latest Visual Studio versions come with Clang Format and good support for Clang-Tidy. And it's not on par with what you can find in Clang Power Tools in terms of customizability and what you can do in workflows and in automation. This raised the bar for all Visual Studio users whether they use Visual Studio barebones or leverage Clang Power Tools. We now have AddressSanitizers in Visual Studio, starting with VS 16.7. We have 64-bit support as well.
Jason: What features though that Clang Power Tools offers sets it apart from the Clang-Format and Clang-Tidy features that are built into Visual Studio now?
Victor Ciura: The workflows, the ease of use, and the ease of configuring it. You don't need to manually fiddle with config files and know all the flags by heart. It does everything behind the scenes and you have a very simple, intuitive user interface over that thing. And on the second part – helping with automation and continuous integration efforts.
Rob: I want to interrupt the discussion for just a moment to bring a word from our sponsor, Visual Assist. Visual Assist is used by serious C++ developers across the world. It's got great cogeneration. Do you need to implement methods from an interface? What about changing a pointer into a smart pointer?
Even an Unreal Engine smart pointer. Adding a symbol, you've typed, but haven't declared? Visual Assist will do these and much more. Plus refactorings – more powerful than the ones included in Visual C++. Or detecting errors in code and suggesting useful corrections. Or navigation – helping you move anywhere in your code and open or locate what you need. Or even the debug extensions.
Visual Assist is written by C++ developers for C++ developers, includes everything you need and nothing you don't. It has a low UI philosophy. It won't take over your IDE but will show up when it's useful. It's there to help, not to advertise itself. Visual Assist is relied on by the developers building software you've used, whether that's office suites, operating systems or games, software you use was built with Visual Assist.
Get the same tooling for your own development. Visual Assist supports Unreal Engine 4 and many versions of Visual Studio, including VS 2019 and Community. Get it at wholetomato.com.
C++ myth busting with Victor and Jason
Rob: I know Jason and you, Victor, recently did a stream together. Do you want to tell us a little bit about the C++ myths?
Victor Ciura: I had this idea a few weeks back, and Jason thought it was an interesting idea. We brainstormed offline over a few items. It's inspired by things I've heard, discussions I've seen, questions from students and interns, and mostly controversial staff that you see in code reviews, and stuff that's not always a clear cut.
There are some cases which are debatable. We tried to tackle a bit of all, we did some obvious things, at least for a seasoned C++ developer. It was a lot of improvisation there and we tried to engage the audience and we had quite a few people online with us and engaging over the YouTube livestream chat, we had lots of suggestions there. We set ourselves to be very flexible and let the discussion go either way. And the feedback was good.
Rob: Is it on your YouTube channel now, right, Jason?
Jason: It's on my channel.
Victor Ciura: We covered several things: the weird standard move pattern (like moving the same thing twice in a function call), the uniform initialization and some of the uglier parts of that, pass by value for sync arguments. We discussed hand-rolled string processing versus standard regex, standard optional and wrapping stuff in optional, optional chaining, the Monadic interface for optional, performance worries in code broad, yielding from using optional. What else did we talk about?
Jason: Do you want to pick out one or two, maybe some of the more common myths that you hear about from your other team developers? Some of the ones you didn't talk about.
Victor Ciura: I try to string stuff together that was somewhat related. Just today we had the discussion in code review around the strong type wrappers. I don't know if people are familiar with the concept. Jonathan Boccara had a very nice series of blog posts; he has a library called NamedType for wrapping stuff in strong wrappers for a safer function calling and safer overloads. And BYOND Forum has a strong type library, both are open source.
We discussed some tricky situation where the wrong overload was picked, new overload was added to the overload sets and in some existing code, the wrong overload was picked by accident and caused the bug. We talked about how we might have avoided this, going back, and redesigning the API and thinking about various gnarly stuff. Of course, function argument default values were involved. I want to discuss building strong type wrappers for function arguments too.
Jason: I feel like if it's something that everyone or many people have reinvented many times. Perhaps it's time for us to get a standardized way of doing strong typedefs. I've brought this up on Twitter before. The first time that came up was in like 1997 or something like that in the Standards Committee. And it's no one can agree on what a strong typedef would be. So, it just constantly gets dropped from consideration.
Victor Ciura: And how much functionality to offer, because you can go and do a very complicated wrapper and add all bunch of whistles on there to satisfy various needs and various scenarios.
It's a thin line between a lightweight thing that people want to use and something that fits all scenarios. Library designers have a tough job.
Jason: What was the conclusion in your code? Did you change the API so that it wasn't a problem?
Victor Ciura: In our case, it was an ugly mix. And one thing I already had on the list was converting constructor that wasn't explicit, and some overloads that had default values for some of the arguments. We fixed the API and got rid of the problem, but going back, if we had proper vocabulary types for those arguments, the problems could have been avoided.
Rob: Since it's a topic that we bring up all the time anyhow, how you would feel, let's say, the next point release of Visual Studio or the next 2021 release or whatever, just breaks all the ABI and you must recompile all the things and can't reuse your existing library. There's a problem for you?
Victor Ciura: I'm for it - "the break everything" camp.
Jason: You rely on binary blobs from third-party vendors that went out of business 15 years ago.
Victor Ciura: We have a very limited set of libraries that we consume in binary format, but those vendors are still working on it. I'm trusting them to upgrade.
Rob: I like how the past three versions have been ABI compatible with each other 2015, 2017, and 2019, but I'm fine with breaking it, and maybe the next two or three can be compatible with each other.
Victor Ciura: Yeah, it's time for breaking release, they've been pretty good so far.
Rob: Before 2015, correct me if I'm wrong, each version was a breaking ABI change.
Jason: That was the world we lived in. We just never assumed that we could use libraries from a previous compiler.
Victor Ciura: It was a simpler time. People didn't make assumptions. They programmed defensively, they asked for source code.
Jason: On the other hand, you have the C++ Coding Standards from Sutter and Alexandrescu, which is from early 2000s? Where they effectively say "don't have C++ types on your library boundaries... "
Rob: And use extern "C" everywhere or...?
Jason: And use "what you see" types, don't pass a string across library boundaries. And when I read that, I'm like, okay, that's one rule I will not be following because to me that just broke the point of C++. If I can't have a library that uses "C" strings and vectors natively, then what the heck am I using C++ for.
Victor Ciura: You would be surprised we have a bunch of those extern "C" interfaces. And we have a bunch of libraries that we consume through "C" interface.
Jason: But there's reasons too. I'm not saying, throw that out entirely. I'm saying I don't want that to be my norm, unless there's a reason for that to be what I need to do.
Victor Ciura: At least you don't have any ABI worries there.
Jason: Right then you don't have any ABI worries.
Victor Ciura: "C" is still the lingua franca of Interop. Unless you like COM.
Jason: I was writing objects in C++ near 2000. I needed to expose an object hierarchy with inheritance through consuming with VB 6. I couldn't figure out how to get the COM interface stuff to be properly inherited and reflect this inheritance in VB 6. I asked the VisualTeam and they explained that I needed to templatize the inherited type. That completely blew my mind because I didn't really understand anything about C++ at all at the time.
Victor Ciura: The interaction with COM got a lot easier nowadays. We have simpler activation models, and the usage is much friendlier.
Jason: What actively uses COM at this point?
Victor Ciura: Everything on Windows, if we're talking about the modern Windows, Win RT stuff. Everything is built on top of COM. It's hidden.
Jason: COM is the technology from like the nineties too or something, you know, a long time ago.
Victor Ciura: COM is a very well-designed thing. And the fact that it's being leveraged in modern APIs and in current software it's a well-designed API and survived the test of time.
Jason: Now that we've gotten this far down the road, Victor, can you describe to our listeners what COM is?
Victor Ciura: The simplest explanation - it tries to model an object, an API surface that is independent of the actual implementation. It tries to do a presentation and a description of the types and their properties and their functionality, and it exposes what can you invoke, and what are the types and the type layouts. It's means of describing all this information. There's a language behind all this. It's called MIDL. And you can describe this independently of the actual implementation and independently of the hardware or where the actual code resides. It's an abstraction that allows you to talk to objects, and call functions, and test values, and marshal information although the object you're talking to is in the same process as you, or in an external process or on a different the server. It's an abstraction over API, over hardware, and it allows you to flexibly describe APIs and call methods and share data across the object boundaries.
Jason: Sounding like the same kind of technology has been reinvented a few times. CORBA or MOC is similar or the interface files by SWIG for generating different language bindings.
Victor Ciura: We've seen various incarnations of them but as a design tool, this was a tremendous success. And it's amazing that the whole Windows Ecosystem is built on top of this kind of stuff. It's a very efficient technology.
Rob: Do we want to bring it back to the C++myths at all? Do you have any more myths? Maybe are there any related to COM?
Victor Ciura: No myths around COM, it's just history, right?
Jason: Have you got any other feedback outside of the YouTube stream? Like from coworkers or friends or anything on the myth-busting concept you put together?
Victor Ciura: A few mentioned that they liked it and they can come up with some suggestions, but I think regarding this topic, some people are reluctant to propose something because they're afraid of how it might be interpreted in terms of "is this really a myth?", "is this a popular opinion?". I'm afraid if I present this as myth candidate, it might be interpreted like I'm disagreeing with it, or I'm agreeing with it.
I see people enjoying the idea of debunking common idioms or investigating stuff that they might have seen there on their own. They love that they might use a C++ Weekly episode as a reference: "Hey, about this topic, there's a C++ Weekly episode that talks about this". It's nice to have a reference to anchor your discussions around. In this list of myths, like we call them, they're looking to identify patterns that they encounter and use that as a catalyst for discussions with colleagues or whatever.
I see a good response, but I would like people to be more forward and suggest stuff that we can discuss openly because we can be wrong.
Rob: Before we let you go, Victor, is there anything coming up soon that you want to tell us about or just tell us where we can find you online.
Victor Ciura: You can reach out to me on Twitter at @ciura_victor. I would like to review the stuff we mentioned, the article from Bartek about Visual Studio visualizers, Debug visualizers. And I want to encourage people to interact with the debugger. It's sad that people don't leverage the whole power of the visualizers and expose their own types there. I'd love if more people give that a shot and maybe give feedback to the team to improve the functionality even further.
I want to remind people of Clang Power Tools, we're curious to see more of your suggestions. Where would you like to see this tool being improved? If you like the standalone heuristics that we've implemented in the standalone tool for the Clang Power Form, Clang Format Detector, and the Clang Format Configuration Tool and if you have ideas – give that a shot and see if that works for your team. It will eliminate a whole class of debates around the styles and white space in your code reviews.
I do encourage people to get over themselves and their particular formatting needs and just agree on a format and just enforce it as a part of the tool chain.
Rob: Well, Victor, it's been great having you on the show again.
Victor Ciura: I had a lot of fun. Thanks for having me.
Jason: Thanks for joining us.
Thanks so much for listening in, as we chat about C++, we'd love to hear what you think of the podcast. Please let us know if we're discussing the stuff you're interested in, or if you have a suggestion for a topic, we'd love to hear about that too.
We'd also like to thank all our patrons who help support the show through Patreon. If you'd like to support us on Patreon and you can do so at patreon.com/CppCast. 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 was provided by podcastthemes.com.
- 12 Different Ways to Filter Containers in Modern C++
- More_concepts library
- Blizzard Diablo IV debugs Linux core dumps from Visual Studio
- Visual Studio's Natvis Debugging Framework tutorial