[MUSIC]
>> Welcome to Visual Studio 2022 for C++ developers.
My name is Sy Brand, I'm the team C++ Developer Advocate,
and today I'm going to show you why you should
upgrade if you're a C++ developer.
Before we get started, the mission of the C++ team here
is to make the lives of all C++ developers on the planet better.
That comes with a bunch of different facets to it.
We participate in the standards,
we drive our own proposals,
we help others with theirs, we prototype proposals.
We invest in our tool chain,
our compiler and libraries.
We bring them up to the latest standard.
We improve their performance and their security.
We simplify dependency management with VC package,
which is an open source package manager.
We improve the Visual Studio IDE to make it the
most productive experience that we can.
Then we continue to enhance
the C++ experience for Visual Studio Code as well.
Today we're going to focus on two and four,
our toolchain and the IDE.
On the IDE front, one thing you might have heard a lot today
is Visual Studio 2022 is 64-bit.
The C++ team have made sure that
this transition can be as smooth as possible.
A few things you'll notice is
the new projects are going to target 64-bit by default.
If you have these huge projects which previously you might have
struggled with memory usage should be less than a problem there.
We do want to make the upgrade as pain-free as possible.
You can install the 2015, '17,
and '19 toolsets directly from
the installer in 2022 just by clicking those buttons.
You can even install minor toolset side-by-side as well.
If you have binary dependencies
which you can't necessarily recompile,
we are guaranteeing binary compatibility back to 2015.
If you have those dependencies,
you can still upgrade to the latest tool set.
If you have open-source dependencies,
then you could potentially use vc package
to upgrade to the new toolset for those.
If you'd like to know more about
porting an upgrading specifically you
can check out aka.ms/cpp/upgrade.
A few other reasons you might want to upgrade,
Hot Reload is a new feature in 2022 and has support for C++.
This lets you apply code changes without
stopping a breakpoint or restarting your application.
Injects your changes into the app dynamically and
doesn't trigger a full rebuild up your project.
This is super useful if you're developing
an interactive application like a video game, for example,
where you might want to make a change,
immediately see this reflected in
the running program without having to stop or recompile.
You can even click this little button on the right
here to Hot Reload on File Save.
If you want to know more about Hot Reload,
you can check out aka.ms/hotreloadcpp.
We also want to make sure that Visual Studio is the best choice,
if you're developing on Windows,
but targeting any platform, not just Windows.
Part of that is WSL2 Support.
This allows you to build and debug C++ code on
WSL2 distributions without having to set up an SSH connection.
It has support from both CMake and MSBuild.
We would recommend CMake if you're doing open source development,
but an MSBuild support is there as well.
If you'd like to know more details,
you can check out cpp-wsl2.
Then we also have experimental support for libFuzzer.
LibFuzzer is an in-process coverage guided
evolutionary fuzzing engine from the LLVM project.
If you're wanting to fuzz your APIs in
order to guarantee the correctness and security,
then you can use this.
It's now available in VS 2022
and you pass, /fsanitize=fuzzer.
If you like to know more, you can check out aka.ms/cpp/libfuzzer.
Now, if you can upgrade your IDE, that's great.
If you can upgrade your standard of
C++ as well, that's even better.
It's where we are with C++ conformance right now is
all stable C++ 20 features have been completed.
There are a few defect reports which came in late,
they're bug reports to the standard,
they came in late in the process.
We're still dealing with those but all stable
C++ 20 features are now available under C++ 20 switch.
We guarantee that these are ABI stable
and they're production ready.
We also have some C++ 23 features,
all of which are actually being contributed by all
of you folks to our open source standard libraries. That's create.
Coming next, we are focusing a lot on
standard library modules and coroutines,
both the proposals going through
the standards and implementing them in our tools.
On the STL, specifically,
we have 115 C++ 20 features
completed and a bunch of those are being contributed by you.
Thank you so much for all of that.
You can see the graph here for C++ 20 features.
You can see that little bump at the end
is those defect reports coming in,
but we're starting to get all of these back down again.
You can check out the most recent data at Microsoft.github.io/STL.
Now, I'm going to demonstrate the four main features of C++ 20,
all working together in tandem.
I'm going to create a new project on MSBuild Application,
and I'll call it launch.
This gives me a new project,
I want to show, ranges,
modules, coroutines, and concepts all working together.
I'm going to show a little random number generation example.
I'm going to get a bunch of random numbers.
Random numbers helps if I can type.
I'm going to get these from something called launch xorshift.
Xorshift is a specific random number generation algorithm
which is implementable in
about five lines of code
and actually generates pretty decent random numbers.
Of course we need to seed it with
some high quality seed like four,
then we can say loop through all of them
random numbers and print them all out with a new line.
This is how basic usage is going to look like,
and now we can think about how to actually implement this.
Now, I want to use modules encouragings for this.
First thing I need to do is go into my project properties.
Go to general and language standard.
Foot this from 14 to C++ latest.
Now, I'm going to create a new module.
Add to my source files a new module.
This will create a C++ module interface unit,
which you can see has the extension ixx,
and I'm going to call it xorshift.
This gives us couple of lines.
We have module xorshift which says from here
down everything belongs to the module xorshift.
Additionally, export this and make it available to external code.
Then we have a single function called MyFunc,
which is also exported.
If we got rid of this, then MyFunc
would not be visible to external code.
This is one of the benefits of modules,
apart from improvements on build times,
you can hide implementation details of
your code without having them
leak into contexts that you don't want them.
But we don't want this, we want to namespace launch.
If we want to export everything in here,
we can just say export.
Now, we can think about implementing xorshift.
We want this to be an infinite stream of random numbers,
but for now let's just implement it
as a single iteration of the algorithm.
We'll return a std uint64_t,
our function will be called xorshift,
and we will take a uint64_t as our argument.
Uint64_t is in the stdint header.
Just to show you something,
first, say, I put it here,
this might look fine,
but remember I said that
module xorshift means everything below
here belongs to this module.
Hash include means just take everything
from this header and dump it into this file.
We're saying that everything in here is going to get
module linkage and we're going to get
some build issues with that. This is actually wrong.
If we had an import of some module here,
then this would all be fine.
Modules are designed to handle that.
But for regular hash includes,
we want to stick them up in what's called
the global module fragment,
which we introduced like this.
Just something to be aware of.
[inaudible] find this and we're all good to go.
We can implement xorshift like so we take a seed,
we xor it with the result of right shifting by 13,
then left shifting by 17,
and then right shifting by seven.
The very definition of magic numbers.
Don't ask me how they got these. Then we return the seed.
This is a single iteration of the xorshift algorithm,
but we wanted this to be infinite.
Unfortunately, I don't have infinite memory on this laptop,
so we're going to have to generate these on the fly.
One way we can do that using coroutines.
Coroutines are essentially a generalization
of a subroutine or a regular function.
A subroutine will enter up here at the top.
It will exit at return statements or flowing off the control flow.
One entry, some exit point.
A coroutine instead can pause or
suspend during execution and then be resumed later.
One of the ways to do that is using co_yield,
which generally means pause execution,
send this back to the caller,
and then we can be resumed later.
We're going to stick this in an infinite loop.
Now we're getting build errors because we
haven't included coroutine traits.
But there's something more here.
Co_yield doesn't actually have built-in behavior.
You have to tell the compiler
what co_yield should mean for this specific coroutine.
The way you do that is customizing the return type here.
We want a Python style generator here.
Unfortunately, there's no generator type
in the standard library for C++20.
There should be in C++23,
but we could use an open source implementation.
I have one myself called tl generator.
But if we try this we get build errors
because I don't have tl generator installed.
It's open source so I could use vc package for it.
I do have vc package installed on the system,
so I could just install tl generator from the command line,
but I want to show you manifest files.
Manifest file is similar to,
if you've used NPM for JavaScript or Cargo for Rust where we
declaratively say things about our dependencies and our package.
We have a name, we're going to call it launch,
we have a version, string.
I'm going to do 1.0.
Then we have dependencies.
This is a list of dependencies.
You could actually put versions here or
minimum versions is a bunch you can do,
but for now I'm just going to say tl generator.
There's a port in vc package which tells it how to download,
and build, and install this library.
I save this to the root of my directory in vcpackage.json.
Then the last thing I need to do to get this to work
is to go to my project properties,
configuration, vc package,
use vc package manifest, yes.
This will tell the build system to pick up the manifest file.
Now if I built my solution, we should see this happening.
Now, the first thing which happens before vc package is
MSBuild scans the sources for module dependencies.
You do not have to tell MSBuild
the order in which your modules have to be built,
it will work it out by itself.
We don't have this for CMake yet,
but we're working on it with Kitware.
After the module dependencies were scanned,
then vc package run and you can see the install tl generator.
It'll also install the couple of
transitive dependencies which tl generator has.
It even used some cash binary packages which I
already had on my system, which is pretty handy.
It told us if we're using CMake,
then we could just copy paste these in.
Enter them slightly, then we've
got a bunch of build errors because we haven't finished yet.
But that should be enough to come up here and say
include tl and it found the installation,
it's a local installation.
This is not going to affect any other projects in our system,
tl/generator and IntelliSense found the file.
Great. Now we can go to launch,
conclude that, and then import.
There we go. IntelliSense there found
xorshift because it scanned
through the dependencies and it knows what file it's in.
We can import xorshif.
Now IntelliSense worked out this type and everything's fine.
We could run this.
It would give us an infinite stream of random numbers.
Let's say we want to reduce
this infinite stream of random numbers a little bit.
Say we want them to be in
the range of 0-100. How could we do that?
Well, one way would be with ranges.
We could say hash include ranges.
Ranges are a way of essentially building up a pipeline of
operations on ranges of data.
One way we can do that is saying pipe this,
this is a Unix pipe,
a bash style pipe.
Pipe this into std::views::
now we get a list of all of the view adapters
in the standard library which are available to us.
You could use your own or other ones which are open source.
One thing to know is if you used range B3,
the precursor to all of this and an older version of VS,
then you probably find that
IntelliSense really, really struggled.
We've done a lot of work on this.
You saw that that was pretty much instantaneous.
If I say, I want to transform it then IntelliSense works,
it says, you need a function here.
We're going to parse it a Lambda
which returns i mod 100, let's see.
Now we can try running this.
We should get out an infinite stream of random numbers.
Here we go, from 1-100.
Great. Say we actually want to
change this slightly and see it update in real time.
I talked about hot reload earlier.
I have hot reload on File Save turned on.
If I go and change this to a larger number and save then
it will recompile while it's running
and we see the change immediately.
Cool. But say we don't want this to be infinite,
we want this to be bounded,
we could instead say pipe this again
into stood views take and take the first five, for instance.
This should print out, there we go,
five random numbers.
Couple last things.
Usual navigation experience you
might expect for modules is all there.
If I control click on the module name,
then it goes to the definition.
Let's say I want to stick a breakpoint in here.
This is a coroutine, so there's a bunch of
compiler magic which is going on here.
This changed into a state machine
and split up into different functions,
but we make it all look like it's just regular code.
If we step over this co_yield in
this time this coroutine has been suspended and then resumed,
but we make it look like it's just going
on like a regular function.
We even have a coroutine frame visualizer
in case you're writing your own coroutines.
To recap, we saw modules with
build system support and go-to modules.
We saw coroutines with debugging support,
we saw ranges with IntelliSense all working,
and we saw concepts.
Concepts are what underlie ranges.
That's how we saw those working.
To reiterate, the mission of our team is to make lives of
all C++ developers on the planet better through standards,
through our tool chain, through vc package,
through our VS IDE,
and through the Visual Studio Code experience.
If you'd like to know more about some of these,
we do have a couple other talks today,
one on game development and one on cross-platform development.
Please do check those out.
Other than that, I do hope you will go away and upgrade to VS
2022 and let us know what you think. Thank you very much.