CppCast - Intro to Modules
Episode Date: April 2, 2020Rob and Jason are joined by Daniela Engert. They first discuss a blog post on a new static analyzer feature in GCC 10 and Jason's plans to port the classic DOOM game to C++. Then Daniela gives Jason a...nd Rob an introduction to Modules in C++20. News Static analysis in GCC 10 C++ Annotations v11.4.0 Jason's live Doom port to C++ Friday morning Links Modules: The Beginner's Guide Slides Socializing with {fmt} - Daniela Engert - Meeting C++ 2018 Sponsors PVS-Studio. Write #cppcast in the message field on the download page and get one month license Read the article "Zero, one, two, Freddy's coming for you" about a typical pattern of typos related to the usage of numbers 0, 1, 2
Transcript
Discussion (0)
Episode 241 of CppCast with guest Daniela Enger, recorded April 1st, 2020.
Sponsor of this episode of CppCast is the PVS Studio team.
The team promotes regular usage of static code analysis and the PVS Studio Static Analysis Tool. In this episode, we discuss static analysis in GCC 10.
Then we talk to Daniela Engert.
Daniela gives us an intro to modules C++ developers.
I'm your host, Rob Irving, joined by my co-host, Jason Turner.
Jason, how are you doing today?
All right, Rob, how are you doing?
I'm doing okay.
For listeners who are watching the video for this one on YouTube,
I am in a different room than normal.
Just to get myself better set up for the next few weeks,
I'm up in my guest room so I can have this room to myself
instead of sharing it with my wife and kids.
You might want to get something other than backlighting
if you care about the video because your face is really dark yeah i i do have a light in here but the the window is still letting in
some light behind my head and making it a little dark on me yeah i can make my lighting a little
better but then i just blind myself so i'm not gonna bother with that yeah maybe i'll have
something better for next week anything okay everything with you, though? Yep. That's good.
Normal life here, pretty much.
Okay.
Well, at the top of our episode, I'd like to read a piece of feedback.
This week, we got tweets after last week's episode with Cy and Kevin Cadoux from Microsoft.
And Patrice Roy tweeted that Kevin is actually one of his ex-students and he now officially feels old.
And Kevin replied, Patrice
is one of the best C++ teachers he ever
had, if not the best. And I just
thought that was nice to see and
I didn't
think to ask who his teachers
may have been, but maybe anyone who
is from Montreal, we should ask them if they
know Patrice Roy.
Probably.
Well, we'd love to hear your know Patrice Roy. Probably. 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 speakass.com.
And don't forget to leave us a review on iTunes or subscribe on YouTube.
Joining us today is Danny Engert.
Danny has a degree in electrical engineering and has worked for more than 30 years now
in the development of a wide variety of software and hardware projects, mostly in the domain of digital signal processing and its
application in areas like signal and communications intelligence, medical imaging, and now industrial
non-destructive testing of steel goods. Danny, welcome to the show. Hi, Rob. Thanks for having
me. And hi, Jason. Nice to meet you again. What really caught my attention there,
industrial non-destructive testing of steel goods,
what does that look like?
Well, actually, the project that I'm working mostly on
is inspection of railway axles.
If you know, the high-speed trains, quite popular in Germany,
have very special axles,
which have a bore going from one side through the core to the other side.
And every 1,000, 1,000, 100,000, a million of kilometers,
they need to be inspected for cracks and flaws in them.
And, of course, you can't cut them in two pieces to find any kinds of flaws in them. And of course, you can't cut them in two pieces
to find any kinds of flaws in them.
But we use both eddy current and ultrasound probes,
which we stick into the bore.
And from the echoes coming from the outer surface,
cracks or flaws,
we can determine if the axle is still fine to run for maybe another million of kilometers.
Wow.
And this has to be done quite regularly.
So this is one kind of steel good that they are doing machines for.
The other one is steel plates in steel plants, steel mills.
For example, if you have
a steel plate 20 meters
long, 4 meters wide and
40 centimeters thick, we can
look into these steel
plates and determine if
this plate is good enough to
become a pipe or something like that.
Interesting.
And another quite popular product of ours
is inspection of
bearings,
the big bearings, for example,
for windmills and this kind of stuff.
Oh, okay.
Do these, like,
ultrasonic probes
and whatever, do they generate a lot of data that you have to analyze?
They actually do.
A couple of years ago, I've been developing an ultrasound device for this kind of inspection,
which would generate at the AD converters about one and a half gigabyte per second.
One and a half gigabytes per second, okay.
Gigabyte per second, yeah.
16 ADOD converters and then an FPGA behind it to condense the data a little bit
and then putting it over a USB-free line to a PC and processing it over there.
Oh, that's fascinating.
So you have to do the FPGA for pre-compression so that it doesn't saturate the USB connection?
This is right.
On USB 3, you get about, well, actually achieved 350 megabytes per second.
So I had to condense the data down from 1.5 gigabyte down to 350 megabytes per second.
And this is what the FPGA was doing. And I did
the whole stuff from
the analog digital design,
the FPGA design,
the communication protocol, the
device drivers and the application
program.
This is the stuff that I really
love to do.
This is application of digital
signal processing. I'm even more curious now like uh
because i have no idea how hard it is to implement something like that in fpga are you doing like
complicated compression algorithms like bzip or are you doing like rle or something just to get
it down to what you need no this is not that kind of data compression that we're used to. It's actually you throw away data which is not interesting.
For example, if you have a certain bandwidth that you're interested in
and you throw away all this stuff that is outside of this bandwidth of interest,
you can then convert the data rate down to a manageable level. This is the kind of stuff
what the FPGA is doing. This is called linear signal processing, where you just pull out the
part of the sample data which is really necessary to find the flaws in the steel goods.
So compression more like from a signal perspective than from what I'm thinking of file compression.
Actually, yes.
This is exactly what this FPGA is doing.
Wow.
So how long have you been working on that project, if you don't mind?
A couple of years.
Okay.
And it all works now.
Well, actually, it does work, but it has a couple of flaws in there.
And we have a contractor which was supposed to implement my design into the FPGA.
And this contractor, well, let us down a little bit.
So this product is not yet in production.
That's unfortunate.
Quite unfortunate, yes.
But at least now we can do it on Windows 10,
so the USB connection is much better than on Windows 7.
Oh, that's good.
Delay the project until the software catches up.
Yeah, yeah.
Sometimes there's a really good thing in bad things as well.
So just out of curiosity now since we've discussed
this do you know how like how many years or months or however long it takes for a million miles on
one of these high-speed trains like what is that or a million kilometers i mean oh probably less
than a year that's the new year okay so that's probably it means a lot if they can certify those
and not just have to replace them on a fixed schedule or something like that.
It probably saves a lot of money.
Yeah, this is true.
And actually, they try to avoid longer maintenance because a train earns money only if it runs and transports people or other stuff.
And so, this inspection has to be really quick.
Right.
So the inspection of a whole train should take no longer than a couple of hours or so.
So you need specialized machines which can do that.
And this is the kind of machines that they are building.
That's neat.
Yeah, very cool.
Okay, well, Danny, we got a couple news articles to discuss.
Feel free to comment on any of these, and then we'll start talking more about modules, okay?
Okay.
All right, so this first one we have is static analysis in GCC 10.
There's a blog post from the Red Hat developer blog,
and it's all about a new F-Analyzer option
being added in, or was added in GCC 10.
I thought you would be interested in this one, Jason.
I was.
And I went all the way through this article
and I noticed a theme.
I don't know if either of you noticed it,
but throughout it, the author says,
oh, with C code, with C code,
and every single example is with malloc and free.
Yeah, I've been noticing it as well.
And my thinking is, okay, this is the kind of problems
that I have never been experiencing in the past 10 years.
Now with C++, even without this checker.
I love the optimism, but what I noticed is that
if you go into GCC and put it
in C++ mode, it does not
do these checks at all.
You can write the exact same code
and it doesn't run it. You have to put the
compiler in C mode, and
then it will run these checks.
Even worse.
Yeah, what's the point of that? I mean,
if it's the same code, why couldn't you run it in C++ mode?
I don't know, but there is a hint at the top saying that once this gets more mature, it'll be enabled for other languages.
Yeah.
That's good.
So for any of our listeners who are writing pure C code, yes, use all the tools that you have available to you, including this new F-Analyzer from GCC 10.
Yeah.
I mean, it looks really good.
The diagnostic flow that it prints and everything,
it looks amazing.
It really does.
This is true.
Yeah, there's some nice ASCII charts to track
what exactly happened with your pointer
that you deleted twice or something like that, right?
So the question is, what took more effort in the implementation,
the size pictures or the actual analysis?
That's a good point.
That is a good question.
Although I will say pretty ASCII really makes me happy,
like looking at something like this, I'm like, ah, you know, that's like,
that's pretty, I like that.
Okay. The, the next thing we have is, uh, this link for C plus plus annotations version 11.4
and Jason correct me if I'm wrong, but this, uh, website looks very familiar to me. So I think we
have mentioned it before on the show, but, uh, it's been updated with C plus plus 20.
And I agree.
When I first saw it, I thought, have we already talked about this before?
Did Rob make a mistake?
No, I think we have mentioned it before.
It's just been expanded with information about all the new features added in C++ 20.
And it looks like a very verbose resource for explaining all the different features
available in C++,
including the newest version. Well, actually, this document was very new to me,
and I've been digging into it a little bit, and at least I read the first three chapters or so.
Oh, wow. And there are pieces in there that I'm not too happy with. For example,
there is a
section on functions as part of
structs, which is actually
what we call in C++
classes.
And
there is a subsection called
data hiding, public, private
and class. And I find this
extremely misleading
because data hiding has nothing to do
with access of members of classes.
And so I think the term hiding is not appropriate here.
The hiding is something that applies to names and scopes,
but not to the accessibility of members in a class.
Yeah, makes me think of the testing trick that some people do,
which I abhor, like pound-define, public-private, whatever.
Yeah, you don't really get true data hiding for sure with Accessment and C++.
Because the point is, the hiding is something that applies to name lookup.
And name lookup is the very first thing
that a compiler does
if it encounters an entity with a name.
And after the name lookup
comes the overload resolution, if at all.
And after that, you have decided,
okay, I mean this name,
and then I only see, okay,
can I access it or can it not? But the name itself is visible. It's not hidden. So the term
hiding is totally inappropriate here, in my opinion.
I'm not going to argue with you. I did try to look at it a little bit from the perspective,
because the intro kind of says that it's meant for people who are familiar with C. And I was thinking, okay, is this a good resource for
people who are familiar with C, learning C++? I didn't really come to a strong conclusion
myself either on that. Well, my impression is the newer parts are much more
correct in this kind of sense, but the older
parts probably not as much.
But on the other hand, one of the very new
parts is the mentioning
of modules. You wouldn't believe it
if modules are in here.
And I've been reading
the chapter and
I must say, the whole chapter is completely
wrong. It's talking about
Clang modules, not C++ modules.
Oh.
Oh, okay.
Maybe this isn't the greatest resource that we should be putting out there.
Wow.
Okay, besides that, this is all that I've been reading so far.
The first three chapters and 7.2.
It's over 1,000 pages if you were to print it it is wow yeah uh there's a pdf
download that's how i know that i didn't you know go print a thousand pages or anything like that
i do have ink coming tomorrow because my printer is out of ink and i do need to print some text
documents soon though but i don't want to use all of my ink on printing this. No, no. Oh, well, so I guess this is a resource,
but take it with a grain of salt.
Except for the modules,
which our expert on the show today tells us is completely wrong.
Well, it might be wrong.
It might be right in terms of Clang modules,
but this is not what C++ modules
are. Right. Clang modules
are more akin to
header modules,
but not
the real modules that we have
in C++ now. Okay.
We'll definitely spend more time on
that in a minute here once we're done
with the news. Yeah. So
speaking of the news jason you
want to make this uh last announcement okay i'm just going to go for a little bit of shameless
self-promotion here i've got um i've been doing some live streaming on my youtube channel recently
and friday morning my time so it's going to be 10 a.m mountain time noon eastern u.s time and 6 p.m 1800 whatever and uh and central european time i'm going to
start a live stream where i'm going to start with the pure c code base that is doom and uh try to
get it compiling with a c++ compiler and i'm going to stream for however long that happens to take. So I expect it'll probably be four or five hours of live streaming of porting Doom to C++.
Now, it's just getting it compiling and getting it running.
And it's not going to be like trying to take advantage of all the features of C++
because it's far too large of a code base to do that all live on the first go.
Get it compiling, see if it works.
Maybe do some initial analysis of how that
changed binary size, because it probably did. I'm not sure. We'll see.
I've been clicking on this link and was a little bit disappointed that it didn't happen yet,
so I couldn't see what you have been doing, but I'm really looking forward to what your effort would result in.
In particular, you mentioned the size problem,
maybe because of RTTI and this kind of stuff,
but probably you can just disable it
and get to a similar binary size line.
And I won't disable it at all.
I mean, at first.
I'm just going to see what happens.
Okay.
And I don't expect RTTI to have a large impact currently
because there's, I mean, since it's a pure C code base,
there's no virtual functions.
So I don't expect the binary to change much.
I can only think of one place where I think it might change with regard
to having to put some stack unwinding
code where I'm going to have to put new
where there's currently a malloc.
But again, I only did like a
one hour practice run, and I
didn't get anywhere close to working, and I'm going to
start all over from scratch again when I do it live
anyhow. We'll have to see what happens.
Which compiler are you planning on
using, and what version of C++?
Clang 10, probably
in C++ 17 mode.
What was your question, Dani?
The comment was maybe
you will see a binary size
increase just because
the runtime library will
pull in the stack
and winder even if you don't use it
anyway.
Right. You're probably right.
And I haven't even looked to see what the actual current binary size is to see.
So even if it added 100k to it, would that even be noticeable?
I don't know. I think the binary is actually quite small right now.
So, yeah, it'll be an interesting experiment.
Starts Friday morning.
Okay, forward tight.
Yeah, so if you're listening to this episode on the day it comes out uh go get on i guess get on youtube while you'll be live streaming it right
i'll be youtube live streaming we'll have a link to it so the youtube link is live right now and
it says there's a little clock down in the corner saying when it starts um And we'll see what happens. Very cool. Okay, so Danny, I think for the past
few years, you know, as C++ modules has progressed through the standards committee, you know, Jason,
I sometimes comment on it in the news. And every time we say, you know, we don't really know a
whole lot about modules, we haven't been following it too closely, even though we did have Gabby on the
show a couple of years ago. So you actually did a talk at Meeting C++. I think it was a beginner's
guide to modules. So we thought it'd be great to have you on to educate us as well as our listeners
about modules for those of us who haven't been following it that closely. Okay, just to make it clear i'm not an expert on modules more of an expert than us i think yes absolutely but um actually i've been in the same situation
as you have you are probably right now a couple well about a year ago i was thinking
this module kind of stuff sounds really interesting because it will help you structure your interfaces
a little bit better than you maybe just get away with using include files.
And many people may have thought in the past that, okay, we are C++ developers.
We are used to have much of our implementation code in include files,
and we have to ship it to our customers if we want to share our libraries,
and we probably don't want to do that.
We want to only make the parts of our interface public,
which is really the interface and not the kind of stuff which
needs to be technically within the header file, which defines or implements the interface.
And the modules kind of thing seems to improve the situation so that you can just
include these parts in your interface
that you really want to export to the consumers of your code.
And this is actually what modules are promising to the users of modules.
It's a more principled way of implementing an interface
to a piece of code, a library or whatnot.
And this is the main benefit of the modules,
at least in the long term.
This is what I would say about modules.
And a side benefit from modules is
that you get other advantages out of it
and other benefits and
for the most part the benefits
at least
the benefit that most people are looking
forward to is an increase
in compile time
in compile
throughput I should say
so and
well
this is kind of a unicorn thing it depends on the situation that
you are in if it actually would increase your compile speed or if it actually would slow down
your compile but this is something that depends on the actual situation and the structure of your dependencies. Dependencies become a real
big thing when we talk about modules, but this is something that we will probably tackle a little
bit later in our conversation. It sounded like you were also saying that we might get true
information hiding here, data hiding, like we were just talking about in that.
Actually, yes.
And this data hiding stuff comes from the simple fact
that a module is no longer a piece of code
that is stitched into your translation unit like a regular include file does,
but a module is something that is compiled on its own.
And as we all know, if you have symbols, names in your translation unit,
these names are not visible outside of your translation unit.
The only thing that becomes visible are the symbols that are generated from the names.
So actually, a module being a completely separately compiled kind of thing hides everything what's in there.
And you explicitly say what part of all the names that exist in your module, become visible to other translation units.
So this is where the hiding comes from.
And the include file compilation model, as we are used to, has actually no real means of hiding anything.
You can make names not visible from a certain point in your program,
but you cannot completely hide it.
The visibility of names in a translation unit
depends on where you are in the compilation process,
but you cannot completely hide it
because at some point you are in a scope
that a name becomes visible.
So this is the main benefit here.
And this is, in fact, this is everything what modules are about.
It's the visibility of names.
Okay.
Everything else is about the same as it has been ever since.
So what you can do with the modules is,
you say you have a translation unit,
which you designate as a module,
and you say, okay, this name and this name
and this name and this name
becomes visible to other translation units.
This is all what you need to actually know about modules.
Everything else is just technical stuff.
So you said in some cases it might give you better compile throughput,
but you said in some cases it might actually make compile times worse?
This is true, yeah.
But we have probably to dig a little bit into modules.
Typically, a module consists of an interface unit and an implementation unit at its minimum.
And this resembles the kind of dichotomy that you have in, say, a library,
but you have a CPP file that you implement, the library and a header file that you have all the interface stuff in.
And what you typically use as the interface include file becomes a translation unit on its own. And this is the so-called module interface unit.
So being a translation unit, it will be compiled separately.
And the stuff that's going to be exported from the module interface becomes something similar to a pre-compiled header.
This is something that a compiler can later on use to get access to the exported interface of your library.
So this means you have a dependency, a compile dependency there.
Before you can use a module, you have to compile the module interface first,
and then you can consume the compiled interface. Rather than just compiling the include
from the library interface
during the translation unit
where you consume the interface,
you have to wait for the compiled interface to exist.
So it depends on how your dependency chain is structured in your project. So if it's a deep
chain, you have a time dependency rather than just an include dependency. Typically, you can say,
okay, each translation unit can compile separately on a different machine, if you like.
And as long as you have the include files available, the compilation process just goes straight ahead.
Okay.
Do you compile one translation unit and that's it.
And with modules, you have at least to have the compiled module interface available to consume a module.
Okay. So this compiled module interface is a compilation dependency.
So in terms of wall time, actually, the compilation may take longer than it has been before.
But on the other hand, if you reuse your compiled module interface unit many times, you can actually get a speedup.
Okay, that makes sense.
It depends on your build machine. If you have infinite resources,
then the embarrassingly parallel
compilation module with include files is probably
faster in terms of you look at the wall clock
at the beginning of the compilation of the whole program
and the finish.
But if you're a typical developer, you're probably much faster with using modules.
In particular, if you don't compile your whole project every time from scratch.
Because you can cache your compiled module interfaces and then you just reuse them afterwards.
And in this case, even deeply dependent, deep dependency chains may become even faster to
compile than with include files.
During my talk, I've been giving an example from our code base where the simple compilation of the interface of a library of
ours took one and a half seconds using the include and 60 milliseconds using the compiled module
interface. So it's quite a speed up if you have the interface module compiled available.
Right. So is the main gain there not having to reparse
tens of thousands of lines of header files or something?
Exactly.
In this particular case, it has been over 900 files,
which would be hidden behind this single include file.
And you can see the numbers in the PDF.
I'm pretty sure the PDF will be in the show notes.
If you want it to be.
You can do.
And you will see the actual numbers that I've been experiencing.
Just to mention it, I have it here.
It's about half a million lines versus five lines.
Wow.
So you mentioned PCH, and now I'm curious.
Do you see in a post-modules world where everyone is using modules for everything that there will no longer be a use case for pre-compiled headers?
I do.
Actually, I think if we start software from scratch, you really should think about not using include files at all.
Only use modules. And if you do so, your compilation process will be much, much faster than if you do proper caching, of course.
Right. proper caching, of course. But to be in this situation, there
is probably much
more time needed just to
have all the tools available
to do so and really take
advantage of the benefits of modules.
But we're not there yet.
Right.
I want to interrupt the discussion for just a moment to bring you
a word from our sponsor.
This episode of CppCast is sponsored by the PVS Studio Company.
The company produces the same name PVS Studio Static Code Analyzer
that has proved to be great at the search for errors and especially typos.
The tool supports the analysis of C, C++, C Sharp, and Java code.
The article 012 Freddy's Coming for You, which has been recently posted,
clearly demonstrates the analyzer's outstanding abilities of searching typos. What about header-only libraries? write the hashtag CppCast and you'll receive a trial license for a full month instead of one week.
What about header-only libraries?
How are those going to change in a world with modules?
Well, actually, it depends on what your expectation is.
If you just want to make it available for immediate rapid consumption as a compiled module interface,
just go ahead and compile it as a translation unit.
There is a feature in C++20 which is called header modules.
You just give a magic incantation to your compiler,
and it would compile your header as a translation unit and spit out an object file
and the compiled module interface. Every entity with external linkage in your include file or
header only library becomes available without any change to your source. Okay. So just use it. This is actually what the modularization
of the standard library
is about.
The compiler vendor will pre-compile
the, for example,
vector or
whatever it might be, or string
and maybe
it would put some of these
parts together into
a larger module and then it's ready for consumption.
And in effect, it's a pre-compiled header, which is totally compiled and is no longer dependent on the ordering in your translation unit as we have been used to in our current translation model.
This is the main benefit from compiling
a header-only library as a module.
Anything that comes out of the compilation process is fixed.
So the source code of the header-only module
is no longer susceptible to symbols that are defined before,
maybe macros,
and they are no longer susceptible to names
which are visible because of include files
that exist literally before the header-only library.
So, for example, if you have a name that is quite popular it might turn out that the same name
exists and could be found by dependent lookup and so your overhead set match may become larger
and you may end up with a better match from a different library or source code that I had before, so that the meaning of your library becomes different
from what the library author has been intending.
And this is one of the benefits of modules.
You compile them on your own,
and the environment of the compilation is totally fixed. So this
has something to do with
definitions, this has something to do
with the ordering
of includes and it has something
to do with
compiler flags which might affect
what's
actually compiled in there, how the
layout is and this is something that you really will benefit from
the much lower chance of getting into ODR violations
because of differences in compiler flags or overload sets and this kind of thing.
So if I compile my module with the Unicode flag set on Visual Studio and then try in the compiled module interface
that allows the compiler to compare the options in effect
during the compilation of the module interface
and the compilation of the current translation unit.
So if you have differences in there,
the compiler would reject it.
And is that something we expect all compilers to do?
Well, if it comes to me, I would expect it,
but I'm not sure if it really does.
If it's required?
It's not required.
The standard doesn't say anything
about the compile environment in this regard,
but it's actually a good habit to do so.
I'm sorry if you don't mind making a quick note on something earlier, because you mentioned including standard string.
And for the sake of our listeners, I don't think everyone appreciates that standard string is not a concrete type.
It is a template that is a basic string on car.
And so to your point that, yeah,
even something as simple as string,
having these headers pre-compiled or something like that could, again,
also you mentioned it with vector,
which is just saying for the sake of our listeners,
in case they didn't catch that.
Yeah, potentially saving a bunch of extra parsing
and template instantiations and such.
Well, actually this turning into modules and header modules, in this case,
applies to every standard C++ header, which is not a wrapped C header.
And this is guaranteed by the standard.
Okay, so it'll be everything for sure.
So if your implementation doesn't come with pre-compiled modules from
the standard library you can do it on your own as long as you know the magic incantation to do so
you keep saying the magic incantation it makes me wonder like uh
so you're clearly using this on your code base right now at work no No, we don't. Oh, okay. The problem is
currently compilers are struggling
with complicated
code.
I did my experiments
and in the PDF
that the readers will probably
see in the show notes, you will see
what the Visual Studio compiler
was giving me as
error messages.
And it was kind of a struggle to make, for example,
Boost libraries be ready to be consumed in an interface module.
I don't understand. It's not like the Boost libraries are complicated.
I'm not sure what you mean. Just being sarcastic.
Yeah, it took me quite a while to figure out what to do about this situation.
And at least I managed to make Visual C++ compile this thing.
Otherwise, I wouldn't have had anything to show in my talk.
But Clang 10 wasn't able to compile this kind of stuff so far.
So there's a long way to go with compilers.
At least this is my experience so far.
I'm really looking forward to retesting all this kind of stuff
with Visual Studio 16.5 out right now.
There's been a blog post on the Visual Studio blog
where a cameraman was saying that they have implemented
virtually everything that is in the C++ standard.
Well, the upcoming standard, it's not really inked.
But yeah, so I will see how far they have come with their implementation right now. the upcoming standard. It's not really inked.
So I will see how far they have come
with their implementation right now.
At least feature-wise, I've been
looking at my comparison table.
Visual Studio is
quite far in this regard.
It doesn't surprise me, given
who works there and is interested on
this topic.
Actually, I've been talking to Gabi
in Prague about the current situation
of the modules implementation
in Visual Studio.
And he says, yeah,
he's aware of there is
some pieces which cannot be
compiled into a
module interface unit so far.
Something the
constexpr kind of stuff will give you
nice messages like
sorry not implemented yet.
Yeah.
Well, that's better than
a cryptic error.
At least you know exactly why it failed.
Yeah, this is right.
But, well, actually my first try
on my first take on modules has been,
I wanted to make the FMT library into a module
because I'm quite familiar with the FMT library.
I've been doing some of the reference implementation there.
Oh.
And it fails spectacularly.
I've been trying for a couple of months to make it work, but every dirty trick
I've been using, none of this would work out. So I had to turn to into something less challenging.
This is something that I've been using from, this is the reason why I've been using something from
our code base here until it came to to boost yeah
so is there currently any build system support that you're aware of i mean does cmake have any
awareness or or whatever well i've been looking into cmake and there has been a reddit post
just a day ago or so where one of the CMake developers said,
yeah, they're working on it,
but it's not in the mainline.
And the only really module-aware build system so far
that I know of is build 2 from Boris Kolpakov.
Okay.
And it was designed with modules in mind
from the first place.
That's cheating.
Bill actually has been
giving some talks
during the past couple of years on modules.
So people who are interested
in it should look up his
name and watch these
videos. And maybe
for experimenting with
modules, which is highly recommended,
it's probably a good idea just to use build2 for
these kinds of experiments, unless you use, for example,
a simple make, or you maybe just use a batch file
with all the compiler invocations in there just for
the very first experiments. Don't bother to
figure out
how your build tool would compile a module.
You can do it in Visual Studio.
It has preliminary support in there,
but this is not really baked so far.
At least it's not up to the task
to take really advantage
of the more advanced parts
of the module specification.
If you're sticking to
simple modules,
this is the kind of stuff that's
specified in the modules TS
and out for a couple of years now.
This can be done with
Visual Studio using the MSBuild
system and
everything beyond
that is something that needs lots of thinking of
and implementation in ms build and the other build systems as well i'm doing my own add-on to ms build
just to make my compilation but um this is not something that can be used by anybody else's this is really tricky stuff that's uh uh okay so i'm curious um how you
originally got interested in modules if most of your background is in like it sounds like lower
level work and electrical engineering and vhdl and all this stuff. Why modules? Actually, it's super simple.
I wanted to propose a talk to Meeting C++.
This is all that's it about.
And I said, okay, this is something that I want to learn.
I'm really interested in this kind of stuff.
And let's propose a talk.
It probably
won't get accepted at all.
And it was actually
quite popular.
That's great.
So if I understand your timeline, you proposed
a talk, it got accepted,
and now you found yourself hacking
on build tools. Right.
Okay.
That sounds about right.
And figuring out how to invoke, for example,
Clang CL on Windows just to compile a module.
This is something that's even more challenging
than extending MSBuild.
You know what?
You just made me think of something
because, I mean, Clang CL tries...
Well, Clang CL is binary compatible and command switch compatible with CL, theoretically, right?
Right.
So they're also going to have to support, eventually, Microsoft's module format, as well as their own.
Well, today they don't. So the compiled module interface from TEL is totally different to the compiled module interface from Visual C++.
If you look at the binary format of these compiled module interfaces, you will see a big difference in there. As far as I know, the compiled module interface from the Visual Studio compiler
is a descendant of the work
from Gabby and
Piane during their tenure
in Texas AM
University. That's a long time ago.
Yes, this is really a long time ago.
And they had
a science project
where they
have been looking into how you can
represent the
semantic content of
a C++ program
condensed to something
more palatable to a compiler
rather than parsing text,
which is more meant to be
read by humans.
This is the background
and the foundation
of the file format of the compiled module interface
in Visual C++.
At least as far as I know,
this is the information that I got from the compiler team
through the grapevine.
The unofficial answer.
Yeah, and actually this kind of stuff is available on GitHub, if you
want to look at it.
There's a
pull request from Gore, and
there's hardly anything besides that
what's been
going on in the original
study, as far as I know.
I think the actual
IR representation
in the
implementation of Visual Studio
C++ is quite different now from
what you've been
shown on the
GitHub repository from Gabby.
Okay.
Another question our
listeners might have is if
they're C++ library authors maybe targeting some library with C++ 17, is there anything they should do to prepare for a world with modules with their library?
Yeah. Actually, there's one thing that you really need to be aware of. A module, even if it has a name,
it doesn't comprise a new namespace.
So if you want to be sure that your library
is prepared to become a module later on,
make sure that all the stuff that you export from your library
is enclosed into a namespace on your own.
Maybe it's a nested namespace, and it's probably a good idea
and actually recommended by the SG15 study group
that the namespaces that you put in all your exported entities
should resemble the naming parts of your module's name.
And this should also resemble, in some way,
the file structure in your project.
So that you have a kind of correspondence
to make it not too hard for your build system
to actually build your module and to consume your module.
And to not run into possible name clashes.
Name clashes can also happen even with modules if your exported entities share the same namespace.
So modules are not namespaces
and users of modules need to be aware of that. Because if you
look at the
expectations
of users, at least this is
the stuff that I'm reading from
users
on Reddit, for example, or
Slack, people expect
a module
that has a name to
establish a namespace of that name, and this is not a case.
Namespaces are completely orthogonal to modules. Actually, namespaces can be something that spans
multiple modules, even if the modules have different names.
Right. I like this. It sounds like the main point is keep your code cleanly namespaced.
Actually, yes. And this is so important in your design of your interfaces.
And if you do it wrong, modules wouldn't help you in any way.
Right. I feel like my favorite takeaway from what you just said is,
it also means you can't use macros anymore since they don't respect
namespaces. This is true with one small exception. And the exception is header modules will taint
your translation unit. So for example, if you have a header file, which you turn into or compile into a header module,
all macros which are part of your
include will
exist even
after the import
of your header unit.
Okay. So, in this sense,
they taint your translation unit.
So, we shouldn't
use them then.
Yeah, but this is true.
And you should strive for not leaving macros behind.
But in some cases, macros are part of your interface.
So in this case, a header unit is actually a good thing to have at hand.
So you can take the benefit of pre-compiling the kind of stuff
and not being susceptible to other macro definitions
or other names which would increase your overload set
and this kind of stuff.
But you can still export modules as part of your interface.
Okay.
So you have everything you need to structure your existing interfaces.
For example, if you would think about modularizing Qt,
this is something that I'm looking into.
And Qt has a ton of'm looking into. And Qt
has a ton of macros
which are part of their interface.
You can only go with
header units in this case.
And it's actually a good thing.
Otherwise you wouldn't have
any chance to use Qt
in a modules world
and as a module itself.
And this is really something that I'm looking into.
Just saying.
Sorry. Go ahead.
Is that something you're looking to
submit back to Qt to help
them modularize?
Well, I'm actually just
a user of Qt and
actually a really old one.
We are still on 4.8.
So hardly anybody is interested in something that's tailored to this really old kind of stuff.
But we didn't have any reason to use a newer version of Qt so far.
I can compile it with any modern compiler so i just thought myself wondering
when was cute 8 released it looks like 4.8 was 2014 maybe maybe even older maybe older it's hard
to like get a quick answer to that because there's been so many patches and whatever to it yeah
yeah i have additional patches on top of it to make it compile on Studio 2019.
2012?
Sorry, I just became completely...
Yeah, it looks like 2012.
Sorry, I'm done.
It's okay.
Yeah, this is the reason why we can't compile
our source code with
any compiler since
2010.
It supports really old code.
Wow.
So I kind of want to come back to this timeline here
that you submitted a talk to Meeting C++,
and then once it was accepted,
you had, it sounds like, a lot of work to do.
Yeah, I was...
I couldn't believe it.
Wow, I've been on vacation in France,
and I got the information that your talk is accepted.
And I said, no, please don't.
So do you recommend that, though, to other people who are thinking about giving conference talks?
Totally.
Okay.
Totally.
You put some pressure on yourself just to make this talk happen
and you learn a lot
actually
this kind of
digging deep into C++
made me become part of the
C++ committee
oh awesome
that's quite the journey then
this is the reason why
I'm so much deeper into knowing what the core language actually is giving to us
and what kind of improvements should probably be there.
But I'm totally a novice to the standards committee, so I'm just learning.
Well, Rob and I have never been to a standards meeting at all.
I'm thinking about going to Kona,
because who doesn't want to go to Hawaii, I guess.
But we'll see.
Well, if you like to be quarantined for a week, go to Kona.
Well, hopefully, I mean, they still you know well i mean what is it
10 months away so i'm not talking about a human mother situation here i'm talking about the
totally absorbed you won't probably see anything from hawaii this is the reason why i probably
will not be on any meeting in the US because it's
big travel and just seeing
meeting rooms doesn't make much sense to me.
So I'm looking more into the online meetings
which are happening right now.
So November was your first conference
was that your first conference talk?
This is the second one. The first one has been
on the FMG library a year before.
So we expect that talk should be on
YouTube someday, but it is not yet.
Not yet as far as I know. And Jens is
actually also absorbed with other kind of things.
I'm not sure why the video
hasn't been put out yet.
Let's see how things turn out.
But at least the
conference slides are in the PDF
that I've mentioned before.
So I'll put those in the show notes.
And maybe if we get a notice that the video's
been put up, we can update the show notes later as well
for a link to it.
Sure.
Well, it's been great having you on the show
today, Dani. Thanks for having me. And it. Sure. Okay. Well, it's been great having you on the show today, Danny.
Thanks for having me, and it was
a nice experience.
That's fun.
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. You can email
all your thoughts to feedback at cppcast.com.
We'd also appreciate if you can like CppCast on Facebook and follow CppCast on Twitter.
You can also follow me at Rob W. Irving and Jason at Lefticus on Twitter.
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, you can do so at patreon.com slash cppcast. And of course, you can find all that info and the show notes on the podcast website Thank you.