- Good morning everyone. Thank you for coming. I hope you're properly
caffeinated and ready to go. This has been a great week. How are you enjoying CppCon so far? Good? Awesome week. Hope I am not going to ruin that for you. A few months back my
friend Simon tweeted this and I immediately
identified with the problem. But, I said, I'm gonna roll with it. I'm not sure if I'm gonna
do that again, but ... And my daughter keeps telling
me that I do look like Gru, so if it fits. Just in case you're disoriented this is the Victor roadmap for the week. You're in this talk. If you want to catch any of the other ones you have to wait for the videos. Let's get started. We're gonna talk about Better
Tools in Your Clang Toolbox. Why am I talking about this? First of all, I've been coming to these kinds of
conferences for years now and I've always had sort of
a tool envy, so to speak. All the cool kids hang around
the Clang cucumber weather, and, I was kind of jealous and wanted to get in on the action and try out some of the tools
around the Clang ecosystem and play around with them. But, historically, I've been in a team that developed Windows-only applications and we've been working on
our product for 15 years now and we're knee-deep in
COM and in Visual Studio and I thought I would
never get an opportunity to really try out in
production, cool stuff like clang-tidy or any of
the Clang-related tools. So, about a year ago, my friends and I started playing around, more like a hobby, with, We started with Clang format basically, and we tried to experiment
and see how we could use Clang Tools on Windows and
see if we can make them work and integrate them in our workflow. This talk is organized
in mainly three things. The first part I'm going to be talking exclusively about the tools. I'm not sure if all of you have been to the welcome
reception on Sunday night. We had a poster expo where you can still see some very cool posters in the main hall there. You can probably see
this giant poster there. It's all about retrofitting modern C++17 features in older codebases and how we got around to implement our own custom
tools to help us with that. So, I'm gonna spend a little bit of time talking about Clang Power Tools. Clang Power Tools is basically
bringing all the goodness of the Clang Tools ecosystem
for Visual Studio users. I'm talking explicitly
about tidy, compilation and, of course, clang-format. It works in latest Visual Studio versions as well as the previous versions. It's an extension for the IDE, it's free and it's open source. So it does help with this workflow. Initially we developed it internally and, like I said, we tried
to play around with it and see if it can really
help us pinpoint issues and improve our codebase. But, after a while, we decided to share it with the community, and we chose exactly one year ago today. I couldn't have scheduled
this better myself even if I tried. So, exactly one year ago today, I had a session here at
CppCon where we announced this tool that we open sourced and made available in
Visual Studio Marketplace. How are things standing
one year after this launch? We've been surprised by the popularity and the enthusiasm in the
community around this tool and people embracing it and trying it on and sometimes it failed for them. They submitted tons of bug reports and we tried to stay on top of them and fix all the issues that
we encountered out there. People got very creative and used it in contexts far beyond our imagination and we've seen project configurations that well exceed reasonable
complexity limits. So, it's amazing what
people can do with them as build files and Visual
Studio property sheets. It's definitely been a
learning experience for us and, surprisingly, I can confidently
say that debugging issues and seeing other people's
configuration scenarios around trying to use
this tool, ironically, made me better understand
how Visual Studio works and how MSBuild works and how to properly organize and
configure your property sheets. Definitely a learning
experience for us and we'd very much like to
thank the people that got involved very early on and helped out, with their suggestions or feedback or even pull requests and ideas. I wanna give a shout out to
my friends Gabriel and Ionut that really, really, they're the brain behind this wonderful product. If you're interested, you
can definitely get involved. The project is open sourced. At least you can submit bug reports if you try it and it doesn't work for you, and we'll try our best to make it work. We started with a PowerShell
script, to be honest. We didn't start with a productivity IDE integration scenario. We initially started
building a PowerShell script and we still maintain it today and we use it for CI automation because we want to keep
building our codebase with Clang to see that we don't have
any regressions on that front and we've enriched this script and we're actually dogfooding ourselves. It works directly on
Visual Studio project files or MSBuild, for that matter. It does support compilation
and tidy workflows. It does not do any roundtrip conversion and it doesn't generate JSON
Clang compilation database. We do have that as a feature request and we're thinking
about implementing that. But, definitely, we would try to automate this process of
generating the compilation database and avoid putting the pressure on the user in terms of describing the
project configuration by hand. It does support parallel
compilation of translation units and it does support pre-compiled headers. This is very big for us. We make extensive usage of pre-compiled headers in our project. And it does help speed up the builds. Of course, it automatically extracts all the settings from
Visual Studio projects, include platform toolsets, directories, PCH information, everything. It has a very rich interface
in terms of automation. These are just a few of the inputs which is that it supports and, like I said, we're very interested in keep using this in our workflow and, we've definitely improved the script as a consequence of this. You can run the PowerShell directly by specifying all the parameters required. So you do gain low-level
access and configurability over every little detail of its behavior. But, it also supports
a configuration file, so you can safely configure
any project-specific behaviors or parameters that you can put in source control and
share with your teammates. This is how it would look like, some very simple examples. For example, compiling a whole workspace, if you don't give it any parameters, it actually tries to
detect all the solutions in the current directory
and browses all the projects and compiles everything in there. You can be explicit about it. You can ignore on certain criteria with regular expressions and everything. Basically, what you would
expect from this kind of a tool. You can run tidy workflows on specific projects or specific files. You can even tell it to
automatically apply the fixes. Basically, it just pipes down all the expected tidy commands
onto clang-tidy itself. This is how a configuration
file might look like, a very simple one. This is actually the one
that we're using internally, more or less. So you can definitely avoid giving all those switches every time. Very important for us, we do
use Jenkins for CI automation and the Jenkins PowerShell
workflow is very important. I just wanna give you a
very quick overview of how you would configure something like this. You would need to install the Jenkins plugin for
PowerShell, for example. That's in Jenkins plugin library. You would need to
configure a PowerShell job as a build step. You can add the commands. This is where you can be very specific for your project needs
or your build job needs. We can even make it be
triggered by an STM change or something like that. The workflow that works best for us is ensuring that every change
on development branches do passes the pipeline and
we don't have any regressions in terms of the project actually being compilable with Visual Studio but, not compilable under LLVM. So, we do try to make sure that each pipeline passes only if
the LLVM build actually passes. We even have triggers. We use Slack internally and
we even use notifications about build failures
around this Clang job. Even emails, some people prefer
to receive reports via email rather than Slack. The built-in output and
errors are right there in the email content itself. And, of course, the
thing that really touches everyday work of the
developers on our team is the integration in the IDE. This is where the Visual Studio
extension comes into play. It's available in the marketplace You can just install it. You go to updates, of course. Highly configurable. You can, basically, tweak
every knob in there. You can even pass flags directly to the gcc driver for Clang. You can be incremental in your approach in embracing LLVM compilation. You can suppress lots of
warnings in the beginning and, as soon as you're able
to fix more stuff and strive towards ISO standards
compatibility in the codebase, you can be more strict and eliminate some of the ignored
warnings along the way. You can be verbose and see detailed output when stuff doesn't work and investigate dependencies
within the projects and problems within contextual variables in your MSBuild files
and see problems there. For the tidy workflow, we found that tidy workflow works best
for us in manual scenarios. So, we run it occasionally and try to see various passes and
we're being very selective about the actual checks that we run and we don't run everything all at once because we wanna be very explicit about analyzing a particular
kind of, for example, modernization pass. Let's say we're focusing on range for or we're focusing on, I
don't know, equals delete or the full constructors
or something like that. So, we're actually using, almost exclusively, the autofix option. So, we're very much relying on our git-gui to see the changes and
examine the changes carefully before we except any of the
automated fixes applied. We do have most of the checks built in, but you can, of course, specify them explicitly, for example, using wildcards or selecting multiples passes at once. The integration in the IDE
itself is in the usual places you would expect to see it. Contextually on a per-source file basis, per project, either
selecting multiple files or compiling or tightening up a whole project or a whole solution. So, in the usual places you would expect to see such an integration. An interesting part in
the integration scenario, the one that I love to use, is that we do have a setting by which, each time you
successfully compile a source file with Visual Studio, it automatically tries to compile it with Clang in the
background 'cause, usually, we see problems there. So, if it successfully passes
Visual Studio compilation, which is what every developer
on the team expects, you immediately see if
it's also okay under Clang. Of course, the IDE integration is natural and uses the standard
output panes and error panes and has navigation to issues
and you can filter them out and you basically leverage all the power within the IDE itself as if this would be the de facto compiler in the iterator itself. For example, if we're analyzing
on a static analyzer report, you can see the actual information, the output from tidy in the output pane. Sometimes it's a little bit difficult to reason about such an output in this dense textual
format in the output window. Our plans are to surface such information in a much more friendlier way as tool tips or hovering the code itself where the problems reside and maybe even implement
something on top of preview windows like Code Lens
and much fancier GUI features in the IDE itself such that you would have much more cleaned-up information
about the analyzer report or the warning or the error
in such particular case. And it would be contextual to where you're actually focusing
on in the source code. Because we find this is
rather difficult to digest especially if there are many,
many, many warnings issued by the analyzer and, yeah,
it's kinda difficult to follow. But, why do we care about all this? The reason we care about this is, we've been working on our
codebase for 15 years now and, in some parts of it, it really shows. It started pre-C++11 of course. When we are dealing with
millions of lines of code it's unreasonable to
expect to change anything just for the sake of change and it's out of the question
to do it manually, so we've been very happy to be able to leverage modernization
passes from clang-tidy and be able to do transformations at scale on our source code. This has been very
important for us in terms of morale, more than anything else. It's much more pleasant
to work on a codebase that looks and feels modern
and uses modern constructs. We've always been on the bleeding edge. We've always upgraded to the latest and greatest
from Visual Studio. But, it's very straining on the eye to see parts of a source file with leveraging modern features and modern library facilities
and language features and, within the same file, you see some old, contrived, ugly
constructs from C++98. You want uniformity in that regard. Being able to do
modernization passes at scale actually led us to have a more cleaned-up
source code and uniform. For example, a very simple thing like think about range for
loops and avoiding all the long lines of complex iterators, and combining range fors with
auto or something like that. So, definitely very pleasing
and it did help morale. Although this kind of tool
induces friction within the team when adopting it initially,
because you do have to deal with all kinds of new warnings and errors that you didn't see before, and, yeah, typename appears a lot in warnings. So, that's just because MSVC compiler didn't have two-phase lookup for 20 years. So, what are you gonna do? It is frustrating when
you're getting in, but, the team was very receptive
in embracing this tool and tolerating all the warnings and issues that they had to fix because of the benefits and the end result being a much
cleaner and modern-looking code and being able to actually
enjoy programming modern C++. We've been doing that and we're very happy with it. I always like to probe the room and see how far along are we
on standards usability? Any of you stuck on old
compiler toolchains? Few of you. C++11? I still consider this old now. Okay. 14. About the same people. And 17 now. Oh, oh. Not bad, not bad. Yeah, not bad. Yup. We wanna get there and, we need tools to help
us because, like I said, it's not pleasant
embracing new features and giving special attention and love to certain parts of your codebase and have all the other
millions lines of code looking like crap. So, you do need tools to
help you there and, yeah. The second part of my story
is about massaging the code. Basically, you do this for two purposes. One, I mentioned earlier, is that you do want standards conformance, even if you're not
doing any cross-platform or cross-tool compilation. So, you do want ISO
standard C++ conformance, just for the sake of being future proof and not have any surprises when your compiler gets updated. The other thing is, you wanna find bugs and subtle things that you've
been ignoring for years. I know I've seen some ignored
warnings in my codebase. As a rule of thumb, we do use W4 and WX. So we treat every warning as error and we're using level 4. But, we do have certain places where we explicitly ignore some warnings. We know why. Yeah, sure. - [Attendee] I'm just wondering
if you're to the point where you can use permissive- yet. - This is my next slide. (laughing) (attendees laughing) You're thinking ahead. We're explicitly ignoring some warnings. Definitely. And, this is interesting,
when compiling other Clang, sometimes you need to get around that too. Regarding permissive-,
we're trying to get there. We're not there yet, but
I am not feeling guilty because of this. Yeah. - [Attendee] What does permissive- do for those of us who don't know? - Yeah, good question. What does permissive- do for me? permissive-, basically, gives you the good
compiler from Microsoft. (attendees laughing) It's the one they don't
wanna tell you about. I think it's on by default
for newer projects. But it doesn't get upgraded
for your old projects. So, this flag basically
enables the modern compiler, the one that actually has
an ASD and two-phase lookup and supports all the fancy
constexpr functionality and the reason it's an explicit flag is that it breaks everything. The main thing that's problematic for us, we've been fixing permissive-
issues in our codebase but the problem, big, big
problem, is the Windows SDK. They're making big
strides in that direction. For examples, the Cpp/WinRT
subpart of the Windows SDK, Cpp/WinRT is now part of
Windows SDK by the way, it actually compiles the
newer, modern parts of the SDK, Rout good, for example,
most of the UWP APIs for programming the Windows Runtime, those are in good shape. But some of the ugly, older
ATL words in the Windows SDK don't compile under permissive-, not yet. They're trying to do their best, but it's a problem of
synchronization between teams. So they're totally different
teams within Microsoft. There's the Windows, the
old Windows division. Now it's something else. At least it's called something else. They're shipping independently, so, they're doing their
best to fix the issues, but, at the same time, the Visual C++ team works
hard to push and implement all the cool stuff in the C++ standard. So, they have to be strict about it and enforce these requirements
under permissive-. Basically, not flipping on permissive- gives you the ability to access most of the C++17 modern
features in the compiler, but still in a Microsoft-compatible way. Permissive- disables all
non-standard extensions in the Microsoft compiler,
everything that used to compile. And they do need to compile the whole Windows and SQL and Office. Think about how much code is in there. And they're not using Clang
Power Tools to modernize it. (attendee speaking off mic) Yeah. It's a lot of work Fixing permissive- issues, it's not a small task. The thing that we noticed
for our code proper, ignoring the key dependencies, is that, because we fixed all the issues and all the warnings triggered by Clang, we didn't have any permissive- issues. So, we're in good shape. And at each major
upgrade, we've been using the Clang front-end since version 3.9 and at each upgrade, 5.0, 6.0, 7.0 now, new warning classes were
triggered on by default and we're actually using Wold in Clang as the default for our builds and we don't enable any,
except the preprocessor, any Microsoft-specific Clang flags. We're striving for Wextra
but we're not there yet. We still have a lot of
aggregate structures that we do need to fix
and fill up with nulls. Because of the fact that we've started and enforcing and fixing issues reported by the Clang
front-end, we didn't notice any permissive- issues in our codebase, just in related to the SDK usage. A big shout out for the STL team. The Microsoft STL actually compiles cleanly under permissive- and actually requires Clang
7 in the latest versions. We did encounter some issues
around COM GUI, GUIDs, and those were fixed in Clang version 7. Like I said, it all
started with clang-format. It's very easy to get in, very attractive. Building on the success of the adoption of
clang-format in the team, we gained courage to experiment with tidy. And this yielded tremendous
benefits for our codebase. We encountered a lot of subtle bugs and things that either we ignored under
the Visual Studio compiler or things that MSVC
blindly completely ignored and happily compiled. And, of course, lot of best
practice kind of things like uniform usage of override and not having any surprises
around renaming stuff in your base classes and interfaces. Actually, this is one of the most impressive modernization passes we've ran over the codebase
in terms of sprinkling overrides in all the right places and in this way, ensuring a lockdown on being able to confidently rename stuff in your interfaces in your base classes without any surprises. And also, you want uniformity. I hate it when I see a
class with 10 methods and just two of them are marked override and all of them are virtual. So, I don't wanna see that
and tidy really helps here. It was this difficult to start out but we were determined and
it did pay off for us. We've encountered tons of issues. Some of the changes were
mechanical in nature, like the typename, the missing typename and the dependent name lookup. What are you gonna do? You have to sprinkle typename everywhere. But, those are, of no benefit for us. But, you have to do those as well. But, other issues, like
encountering near misses in visual function names or functions that actually didn't override anything, although you thought they did, we did find quite a few of those. Yeah, I mentioned this earlier. Why are we encountering this? It's kind of easy to
get into this problem. If your toolchain allows you
to use non-standard constructs or some fancy language extension or, and I'm not picking just on MSVC here, I'm just using it, but, same goes with gcc, for example. If you're allowing programmers to use some non-standard
construct, they will use it, given a sufficient amount of time, and, you're stuck with it. So, if you're compiler gets
more strict and, for example, needs to implement correctly, requirements in the new standard, let's say, under permissive-, you're gonna encounter those issues and you have to deal with them. Otherwise, you can't move on. I talked about the modernizers
and the readability also has quite a few checks
that we found very useful. And, of course, static analysis. Visual Studio has great
integrated static analysis and it does have the Cpp
Core Guideline checks right in there, but it
never hurts to have more. This is the kinda thing that comes with lots of false positives and you have to really look for the needle
in the haystack there. I thought that we would just examine just a few examples
that we've encountered. For example, frequent offender, delete without a virtual destructor. It's kind of difficult to
figure out when you have a deep class hierarchy but, client immediately picks this up. For example, here, overload virtual. So, we actually had the
virtual functions that had a slightly different signature. Loop induction variable or, in this case, an iterator was incremented
both in the loop header and in the loop body. I don't know how that
escaped code review, but ... Quite a few of these pessimizing moves. Quite a few of these we
found in our codebase. Anybody needs to pick on those? It's all clear why client protested there? I don't need an aside about
RVO and stuff like that, right? Tons and tons of this one, Wreorder. People were not very consistent in declaring their initializer lists and, we had to fix a whole bunch of these. So, this was highly unpleasant. In some situations, we
actually encountered initialization dependency
problems that were dormant there. So this was extremely yucky. Missing field initializers,
a few of those. Not very serious. Another frequent offender,
double user-defined conversions. We had a ton of those, especially around the strings
and the string literals and stuff like that. So we did have to fix a lot of those. And it was tedious. I won't lie to you. Another frequent one, delete
with no virtual destructor. But this time around, shared pointer. Quite a few of those and
people didn't properly annotate their interfaces and
they had shared pointers around interfaces that didn't
have any virtual destructor. Quite a few of those, as well. Another situation here
around a simple interface with unique pointers this time. So, basically it's the
same issue as before. A lot of this. How many of you are still using old enums? Yeah. I can't tell you how
many of these we found. The wrong enumeration being
used in the wrong context. They sound the same, but
it's not from the same enum and it didn't even have the same value. (attendees laughing) So, wow. We found several of these
and I was just amazed that we actually sold
the product, this crap. (attendees laughing and speaking off mic) So, definitely no test coverage there. You can be iterative on
achieving conformance. You don't have to be
extremist right off the bat. You can disable delayed template parsing, throw in Microsoft compatibility switches for the client compiler, ignore the typename thing, suppress particular warnings that are very noisy in your codebase and just come back to them later
when you're feeling better. (attendee laughing) Regarding the clang-tidy checks. Whole bunch of them. I think there are around 300 now. And, but, these I'm listing just the ones that we've successfully
ran over our codebase. Of course I picked on the modernize and the readability ones. Use-nullptr, loop-conversion for range for, overrides was a big thing. Redundant-string-cstr function. unbelievably stupid usages of cstr functions
when initializing strings and copying things unnecessarily. Use-emplace, that was a nice touch. It's debatable about if
it's legitimate or not in certain scenarios. Use-auto, this was number
one favorite in the team. Make-shared, make-unique, instead of actually
sprinkling news everywhere. Equals-default, equals-delete, you wouldn't believe how many empty constructors we had there. Default-member-initialization. That cleaned up things a bit. Redundant-member-initialization. For example, lots of people feel the need to initialize standard string to nothing. I don't know why. Pass-by-value, braced-init returns. I would pick on the worst modernizer pass I have ever seen is use-using. You would expect that to
be the most trivial one. It really screwed up everything. I'm gonna show you some details there. A lot of modernization
and readability fixes around initializing strings
and string comparisons, and, there are some gotchas. You need to be very careful
with pieces of code like this, where an actual C string function was necessary because it was passed
around to a buffer that was longer than required and actually needed a null char there. We actually caught that in code review and doing these automated changes. So you need to be careful
with hacks in your code. Some of the problems
we found, for example, a few of the unique
patterns without the array specialization for make-unique. We found several of these. And, when using auto, it
left us with some garbage in terms of all typedefs that
we used before for iterators and auto cleaned up the initializer but it left all those typedefs
that are pointless now and we needed to clean those up by hand. So, not perfect, but ... In modernizing range-based for loops, sometimes the iterators were
hoisted above the for loop and stuff like getting
the size of the container in the count variable, that thing just remained unused there. At least you can catch those with unused pods and you can clean those up by hand. I'm just being fair and showing
you that it's not perfect. Some manual attention is required. I said about use-using, use-using was by far, the buggiest check we've ran. It screwed up all our function
pointers' definitions. So we had to do those by hand. In certain situations where
we actually used templates this modernizer autofix actually replaced the last
template instantiation, the last type that was
attempted in that template actually used that one
when replaced the using, the typedef with the using. So it actually replaced
the concrete type there instead of the template parameter. So you need to watch out for those. Beyond clang-tidy. We wrote custom tools. We fixed, like I said, lots
of member initializer lists, removed a lot of private
fields in our classes that were unused in any way and didn't have any
side effects, of course, refactored some of the
heavy class constructors when we eliminated a lot of
unnecessary initialization. So, we're striving for Wextra. We're not there yet. And we're improving the extension and we plan to continually run stuff. For Part III, more clang-tidy checks. Tidy checks are organized in modules, which can be linked into clang-tidy with minimal or no code
changes in clang-tidy. Checks can plug in in the
analysis over the preprocessor or with PPCallbacks or, in
the AST, with AST Matchers. Checks can report issues in a similar way with like you would see
any Clang diagnostics, and can even provide automated
fixes like we have seen. So, you can definitely go in there and roll your own and automate the process. There are some scripts
that help you set up the scaffolding necessary
to generate the new tidy that you can write. You can use tools like clang-query to interactively prototype an AST Matcher and explore the AST for
a particular situation that you're trying to address. You can dump the AST and
see how things are laid out and guess what kind of checks you need to provide in the AST Matcher. This would be a typical
layout for a tidy check that you can plug into the existing ones. There's an LLVM on Git mirror there and you can clone it
and easily build them. For example, if we're
implementing a PrettyFuncCheck this is what we would have to do. And initialize the scaffolding and this will generate test for us, will register the module
and generate a skeleton for the check source file. This is how it would look like. You would have to inherit clang-tidy check and the minimal thing you would have to do if you're trying to do
an AST-based analysis, register a Matcher and actually
implement the check itself. So, those are virtual functions that you would need to override. These are called automatically
by tidy, or by the framework, and you just need to do your magic there. If you wanted to do any
preprocessor analysis you would have to register a PPCallback. But those cases are much more rare. For example, we can bind
to a function declaration. Let's say we give you
an identifier as needle. And, later on, we can implement the check and get ahold of our
needle that we matched and, for example, we can check
if the function declaration starts with something like
get underscore ignoring case and issue a diagnostic
and suggesting a fix to start with uppercase
get and no underscore, because that's how I like it. Sure. - [Attendee] Is it possible to register some sort of callback that
can look at comments.\? Like, if you want to see
that all you parameters are documented for your function? - The question was, is it
possible to register a callback to match code comments so
that you can enforce like policies on commenting stuff. Is that accurate? Of course it's possible. (laughing) This is how you would
invoke your custom check. I put this check in the readability module just because it's more readable to have functions with uppercase Get. So, this basically instructs tidy to suppress all the default checks and just run your own. That's what that syntax means, if it looks unfamiliar to you. You can enroll checks
that are configurable. Many of the built-in checks have knobs that you can switch on. For example, the aggressiveness
of a particular check or some kind of class of functions that it looks for when it matches stuff. For example, if it
looks for fine functions or any of the derivatives or what kind of string type to search for or something like that. So many checks are configurable. You can load up configurations for checks and even store them as to
be in dumped further on. For example, here I have two options, an integer and a string,
and I just read them from the configuration. And, of course, there's a standard way of providing check options for clang-tidy. Works, you just supply the
values in a dot clang-tidy file, configuration file. That's just standard syntax there. I just used some symbolic names here because it doesn't fit in the slide. So this is what you would
expect and, of course, you can build it, build your check and your test unit for that check. If you're having trouble to, the difficult part is
actually figuring out what to write either in the
Matcher or in the check itself. So, my example was trivial because that's about what I
can do in such amount of time. But, you can dump the AST
for a particular situation that you're trying to target and try to visualize the AST
and pick out the right types in the AST so you can probe them and see if you can properly identify them within the targeted source code that you're trying to modify or diagnose. I do encourage you to write custom checks for project-specific needs. We're trying to do that. We're still learning to do that. And the most important thing
is to run them regularly. A theme for me this week
has been around strings. I've had two talks around strings, one around strings in COM because there are several
types of strings in COM where there are particular problems, and one around string_view
and how I'm looking into eliminating some of these interop problems in using COM with string_view, especially if we're thinking
about modern SDK-like Cpp/WinRT and its type string hstring. I'm heavily interested
in researching this issue and figuring out the good
practices and all the gotchas and actually trying to automate some of the nitty gritty parts of actually interoping these string types in our application and
do proper data marshaling without any of the
dangling references issues. It's not easy but, I'm
trying to figure this out. And, yeah, we're knee-deep in COM. Our application now has a
very wide API surface area and it makes heavy use of COM and we have several types of string classes in our application and it's always awkward when we do have to see that GLU code sprinkled
all over the place and unnecessary copies being made and unsafe constructions assuming an automated string and stuff like that. Clang-tidy has several
string-related checks and, even one around string_view. It's a more of a general setting. It detects any dangling handle. Its main purpose is around string_view but it's a general check. This is one of those checks
that have a configuration and you can actually specify
a different handle-like class, like string_view, if you have some of your
own in your codebase. So it is configurable. Very hot news. Lifetime profile 1.0, I'm sure Herb will mention
it in a few minutes. So, detecting dangling string_view is an important thing
because it's such an easy way to convert from string to string_view and, basically, you're almost guaranteed to run into dangling references. This is a trivial example
from Herb's paper around it. If you're running a newer version of Clang with a Wlifetime switch on, you can see passing the dangling pointer as argument error there and it immediately picks up
this problem in your code. I do encourage you to see one talk today. It's at two o'clock. It's about implementing
Cpp Core Guidelines' Lifetime Safety Profile in Clang, the thing I just showed you
earlier, the Wlifetime flag. So I'm very, very interested
in attending this talk and I do encourage you to go as well. The Visual C++ team started
a new series of blogposts on their blog around Clang tooling and building with Clang. So, I do appreciate this effort and their articles are very well-written. I put a link there and I
encourage you to read it and I'm very excited to see
the follow-up articles on that. There's a new kid on the block. Another extension in the
Visual Studio Marketplace that, actually, tries to help you build your project with LLVM. It basically gives you another
toolset within Visual Studio and you can basically switch from CL.exe and Link.exe to Clang and build stuff with Clang. For example, if you wanna follow
in the Chromium footsteps. With this, I'm about done. Can't wait to crash in my hotel room after I see all the good talks today. And, thank you. (attendees applauding) We do have a few minutes
if you have questions. Or you can catch me in the hallways and I'll be happy to answer. - [Attendee] I just wanted
to say a big thank you for putting the Clang
Power Tools out there. I'm one of your happy,
one of the 80,000 users that's totally happy. - (laughing) I'm happy to hear that. - [Attendee] I experimented
with it last spring. I've got something close
to 20 million lines of legacy code and-- - Wow, you're really pushing us. - [Attendee] No, I did
about half a million and we picked the modernizations that we
thought were just gonna be really easy, sure to work. And we did kind of a subset
of what you put out there. But the same thing that you just mentioned is what I ran into. We thought the using substitution
would be just great-- - No, that's
- and it just, it just causes havoc. Is that a bug in clang-tidy or, I didn't get a chance to look at my code-- - It's a bug in the check
itself, not in clang-tidy, in that particular check. I'm not trying to shame
the author or anything but I'm really looking
forward to dig into that code. - [Attendee] So the interesting thing is the other option I looked at is there's an extension called Visual Assist from the Whole Tomato business-- - Yeah, yeah, we use it. - [Attendee] And we've used it for years, and it has a subset of
these modern assists and they're using
substitution works correctly. - Yeah, but it's not implemented
on top of clang-tidy. The Visual Assist people, I've been using Visual Assist
for 15 years now almost-- - Yes, the same with us.
- So, they well-precede any of the Clang tools. So, they wrote their own. So they have their own
parsers and everything, so-- - [Attendee] The problem with them is they do one file at a
time and so, as you know, it doesn't scale. Anyway thank you again
and one more thank you is I was on Visual Studio 15.2 and there was a bug in
your PowerShell script. I reported it and somebody
fixed it that night and when I came in the next morning-- - You can thank my buddy
Gabriel back there. He's the one that maintains
the PowerShell script, so-- - [Attendee] Anyway, thank you very much. - My pleasure. - [Attendee] So, another thank you. I had almost exactly the same experience that the previous gentleman had. The one I wanted to call out, I ran into the using type dev and the dot cstr one. We had that happen on us and it happened at runtime
so we were (speaking off mic) But it happened pretty
fast so it was all right. We were able to back it out. - That's tricky, yeah.
- Yeah, it is. But it didn't go to any
customers so it was fine. The other one I wanted to call out especially that I really
like was the header reorder. That one was really nice
to use for clang-format. We had the headers in Oleko styles, so. We had a lot of them where
things were in the wrong order and it found all kinds of
ridiculous header inconsistencies. - Exactly, yeah the
- So that was a nice one - physical versus logical
relationship within the models. We've had that issue as well so, that's related to clang-format
and not tidy itself, but, we've encountered lots
of weird dependencies and transitive includes that
were not supposed to be there. - [Attendee] Yeah, we're
still finding though where people are somehow
windows.h got in there, right, or Boost. Both of those two, I love. I like using Boost, but it has tendency to bring the world in with every header that
you have so that's-- - I feel with you. And my colleague, Theor
there, he's the header hero. He actually cleaned up all our headers so, lots of work there. - [Attendee] It's a rough job. That is not a fun job. - No, he can attest to that. (laughing) - [Attendee] Well thanks anyway. I just wanted to say thanks again 'cause I'm one of your 80,000 too and it's been great. I'm gonna put it on the build server and get it more automated
but I'm not there yet so, I've just been hassling people-- - If we can help in any way,
shout out on GitHub and-- - Okay.
- we'll try to help you. - All right. Thank you.
- Yup. - [Attendee] I just had a-- - Hi.
- practical question. If you can speak to, So you write your own
clang-tidy checks, right? - We're trying.
- Of course but you're trying to.
- We're trying. - [Attendee] I'm thinking like, how, from a practical perspective,
in an organization, do you maintain that? Do you have, I assume,
your own fork of clang-- - If you're talking about
project-specific stuff, you kinda have to because
you're not gonna be able to do any pull requests
and nobody's gonna accept any esoteric checkout there. - [Attendee] So then do you make a binary that you share on your
file server or something so that everyone that's
using your own checks-- - Right now, our usage of clang-tidy in our team is on, it's a la carte, so to speak. So, we're using it, if we're talking just
about the tidy itself, that workflow we're using it manually. So it's not automated or anything. And, we have one or two people in the team that actually try to do those passes and inspect the difs and it's not something that
every developer on the team has installed and configured like the Clang extension itself. So the Power Tools extension, everybody on the team has installed and they're constantly
using that workflow. If it compiles in MSVC automatically background compile in Clang so that it picks up all
the warnings and errors that are Clang-specific. But the tidy workflow, it's something that we
do a la carte right now in terms of I periodically run it and my friend Gabriel runs
it and we report stuff and investigate and
try to patch things up. So, it's not something
that we need to share yet. We're not there yet. - [Attendee] Okay, thank you. - Yeah. Cool. So, we're out of time but, you can definitely
catch me in the hallways and we can chat further if you want. Thank you. (attendees applauding)