CppCast - Constexpr Evaluation
Episode Date: May 23, 2019Rob and Jason are joined by Daveed Vandevoorde to discuss his contributions to the C++ standard and his recent work on constexpr evaluation. David ("Daveed") Vandevoorde is a Belgian computer ...scientist who lives near Princeton, NJ, USA. He is vice-president of engineering at the Edison Design Group (EDG), where he contributes primarily to the implementation of their C++ compiler front end. He is an active member of the C++ standardization committee where he is primarily active in the core language evolution work. His recent work in that context has primarily been about extending the capabilities of “constexpr evaluation”. Daveed is also one of the five members of the committee’s “direction group”. He is the primary author of the well-regarded “C++ Templates: A Complete Guide” (now available in its second edition). News Report from using std::cpp 2019 Exploring undefined behavior using constexpr Linux Development with C++ in Visual Studio 2019: WSL, ASAN for Linux, Seperation of Build and Debug EnTT v3 is release Announcing C++Now 2020 Daveed Vandevoorde Daveed Vandevoorde Links C++ Russia 2018: Daveed Vandevoorde, Reflective Metaprogramming in C++ C++ Templates: The Complete Guide Direction for ISO C++ Scalable Reflection in C++ Sponsors PVS-Studio Facebook PVS-Studio Telegram PVS-Studio Twitter JetBrains Hosts @robwirving @lefticus
Transcript
Discussion (0)
Episode 199 of CppCast with guest David Vandervoort, recorded May 23rd, 2019.
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.
And by JetBrains, maker of intelligent development tools to simplify your challenging tasks and automate the routine ones.
JetBrains is offering a 25%
discount for an individual license on the C++ tool of your choice, CLion, ReSharper, C++,
or AppCode. Use the coupon code JetBrains for CppCast during checkout at JetBrains.com. In this episode, we discuss undefined behavior.
Then we talk to David Vandervoort from the Edison Design Group.
David talks to us about his contributions to C++ and recent work on constexpr
evaluation. Welcome to episode 199 of CppCast, the first podcast for C++ developers by C++ developers.
I'm your host, Rob Bervink.
Joined by my co-host, Jason Turner.
Jason, how's it going in Israel?
That's great.
We just had a really good Core C++ conference last week and technically my second keynote ever.
So it was super fun from that regard.
And yeah, it was a really good conference.
And they sold out, as we mentioned before.
And so, yeah, that's awesome.
Yeah, and then doing some touring around after that.
Very cool. And did they record all those sessions? I was going to be on YouTube eventually,
you know, they were all professionally recorded and I believe they're starting to piece that
stuff together right now, but I don't know what the schedule is.
Awesome. Well, once we, uh, see those go up, we'll have to let listeners know.
Yeah.
Okay. Well, as top of episode, I'd like to read a piece of feedback. This week, I got an email from Professor Daniel Garcia, who is an associate professor in Spain. I can't read the name of the university. But here it's in. Hey, Jason and Rob, thanks for the huge job with CppCast. I think you're doing a great job to make C++ developers feel like they're part of a community. I'm writing to you to call your attention to the last C++ conference we had in Spain, which is called Using Stood CPP.
We have six editions of the conference now.
And he recently wrote a trip report with data gathered from the evaluation forms.
And he shared it.
And I'll put a link to that in the show notes. And yeah, it was just a little collection of data they made
from the attendees at this Spanish C++ conference
about what industries people were working on,
what version of C++, what compilers and IDEs they were using.
So yeah, some interesting stuff in there.
I hadn't moved towards more C++ 11.14.17.
That's awesome.
I had no idea that there was a conference in Spain at all.
Yeah, I had not heard of the Spain conference myself either.
So if you are anywhere near Madrid, it looks like it's located in Madrid,
but they have people coming from other parts of Spain too to attend.
Well, and Conan's even one of the sponsors,
which means our friend Diego probably goes there.
And yeah, I was looking at who the talks were,
and they had our recent guest, Guy Davidson, doing one of the talks as well.
How come none of our guests have ever mentioned this?
I don't know how we haven't heard about it before, yeah.
Huh. Well, I'm offended.
We know about it now.
Well, we'd love to hear your thoughts about the show.
You can always reach out to us on Facebook, Twitter, or email us at feedback at cpcast.com.
And don't forget to leave us a review on iTunes or subscribe to us on YouTube.
Joining us today is David Vandervoort.
David is a Belgian computer scientist who lives near Princeton.
He is vice president of engineering at the Edison Design Group,
where he contributes primarily to the implementation of their C++ compiler frontend.
He's an active member of the C++ Standardization Committee, where he is primarily active in the core language evaluation work.
His recent work in the context has primarily been about extending the capabilities of constexpr evaluation.
David is also one of five members of the committee's direction group.
He is the primary author of the well-regarded C++ templates, a complete guide.
David, welcome to the show.
Hey, hi. Thanks for having me. Glad to be here.
We've mentioned the direction group a couple of times here.
Can you remind us what that does?
Yeah, so a few years ago, a number of national body representatives and some experts got together because they felt there was often some conflict.
And the committee didn't seem to always be going in a single direction when it came to the evolution of the language.
So they wondered if it would be nice to have a group of people who have been with the committee for a while, have different interests, and see if they can agree on general direction and express that in some way. And then they would use that as, you know, one element of guidance
into decisions that are made in the future. And so they put together a group of five people.
Bjorn Strasser, obviously, is in that group, having the longest history with the language.
Biman Dawes was in that group. He retired, so he's the first retiree of that group having the longest history with the language um beeman does was in that group he
he retired so he is the first to retire of that group but beeman um we can thank him for having
uh the standard template library integrated into standard among other things um michael uh wong
who's uh representing all kinds of activities in the committee uh howard hinnant you you probably know him uh we have to
thank him among other things for uh move semantics um roger or is now on this in this group as well
he's a british representative has been on the committee for i think close to 20 years um he's
he's also the chair of bsi um and helps organize the the accu meetings, and then myself.
Cool.
So we're having regular calls, conference calls among the five of us,
and just discuss topical issues about standardization.
And there is a paper, I think it's P0939 or P0959,
that we update with sort of general generalities
about where we think C++ should go in the short term,
medium term, and long term.
So that's a paper that gets republished with each committee meeting?
Not every meeting per se, but we try to have updates every few meetings.
I think so far there have been three versions, I think.
Okay.
What are some of the recent points coming out of that paper?
Anything particularly interesting?
Well, they're interesting if you're into sterilization, I'm sure.
Okay, wow.
And a lot of them are very general.
We don't try to give direction about, here's how you should do this.
It's more general principles, but also about certain topics. For example, one of the things we considered was we think it's important
to take into account education when we design a feature.
How is this going to be taught? And in fact, out of this discussion came
a new study group within the community called SG20, which is focused on
education. It's maybe something we don't think about when we think about how to evolve the language,
but it's really important
if we want to not just carry along
people who have been
using this language for 20 years,
but getting new generations to
becoming experts.
Okay. Well, David, we've got a couple
news articles to discuss. Feel free
to comment on any of these, and then we'll start talking more
about your work with the committee
and some of the recent proposals you're working on okay sounds good uh by the way i i
heard you mention there the the meeting in spain the person who sent you that mail is uh jose daniel
garcia is actually the representative of spain on the committee awesome okay yeah and he's heavily
involved among other things in contracts oh cool, so this first article we have is
Exploring Undefined Behavior Using Constexpr.
And this is from, I'm probably not going to pronounce this right,
Jason, I think you know his name, Shafiq Yagmur, is that right?
I know it's Shafiq.
Okay.
This is a pretty interesting article.
He's basically going over how because constexpr expressions don't allow undefined behavior,
kind of using it as a way to test your code and make sure you're not going to encounter undefined behavior.
And he's going through a bunch of examples and talking about using it in Compiler Explorer to quickly check your code for UB.
And of course, you have to constexpr all the things
if you actually want to be able to do that.
Right.
There's actually some, you know,
you get some sometimes really nice diagnostics from this.
I recently implemented dynamic allocation in constexpr.
And if you have a leak,
not only does it tell you that there is a leak,
but it'll tell you exactly where it leaked, you know.
Because we have to catch all undefined behavior. It's, uh, you know,
the constexpr machine is the ideal C++ machine. So ideal from an abstract point of view, you don't
necessarily like it because sometimes you want undefined behavior or something on a little bit
on the edge. So is that for the EDG front end that you you did that? Yeah, yes, that's correct.
Okay.
And this is going a bit off topic, sorry, but I must ask,
where, how is the EDG front-end used today?
I can't give you a complete answer to that
because a lot of our customers don't want to know
that their technology is actually our technology.
I see.
But if you were to use Visual Studio's IntelliSense,
for example, that is based on ours.
I can say that because they put it on the blog post.
Right.
The Intel compiler,
they have admitted that they use our front end.
I think Coverity, if you know Coverity,
they have a source analysis tool.
They have a paper where they also mention
that they use our front end as a thing that processes everything.
But there's lots of other customers.
A lot of embedded systems compilers, especially in Asia, use our technology.
And you also have your own back end?
No.
Well, we write the front end, and most of our customers are really only interested in that. They'll use that.
Then we represent the program as a graph.
We can lower that to a level where the graph is more or less C-semantics. It's not
exactly C-semantics, but it's the kind of stuff that you expect from C and non-necessary C++.
So something like a virtual call will then be replaced by an indirection
to a virtual function table.
And a lot of our customers use that, some don't.
And then we have a backend called a C-generating backend, which we use for testing purposes.
So we generate C so we can compile it with another compiler like Clang or GCC or Microsoft,
and just to test our output.
Not a lot of people use that. You might remember the Como compiler from 10 years ago.
It was a relatively inexpensive advanced compiler,
and Como was using that module,
but I don't think a lot of our customers do otherwise.
We also actually have a C++ generating module
where if you don't lower the representation,
you can regenerate C++ code,
and then what you can do is tweak the graph representing the program and then having
equivalent C++ code regenerated.
Interesting. It's actually really interesting.
A lot of our customers use
that to instrument your code.
They build tools, not necessarily
compilers, but tools that will insert stuff
in your code. And then they produce
C++ output that's compatible
with the actual build compiler
you use.
We actually emulate most of the major compilers and all of their versions. produce C++ output that's compatible with the actual build compiler you use. Wow.
Okay.
Yeah, we actually emulate most of the major compilers and all of their versions.
So if you're building with, say, G++, 4.8.3, we will emulate that version for you.
Wow.
And so at what stage then?
We're really going off the rails from the news at the moment.
Sorry about that.
I just have to dig in a little bit since you said you just implemented constexpr dynamic allocation.
Is that something that has been officially accepted for C++20?
I'm curious where and at what point in your EDG code does the front end catch that?
Or how does that work?
All right, so it's not officially in C++ 20 yet, or even in the working draft. It has passed
Evolution. So the Evolution working group has agreed that this is something that should go
forward, and they have handed it over to the core working group. So they are now working
on revising the words that my friends and I have written to make that possible. And in fact, I have to update that for the next meeting.
And hopefully in Cologne in July,
core, being the core working group,
will agree that these are the right words
or bring them into a shape where they're correct.
And then the committee will vote that in.
And yes, it's completely handled in the front end.
So everything that's constexpr is handled in the front end.
Yeah, I've never really stopped to think about
who has to actually execute the constexpr
on the abstract machine,
but clearly that can't happen on the back end, right?
The results of it have to come back to the front end
because, for example, it could be a template argument, right?
It's a call into a...
Right.
So maybe you could work together with your back end but that that violates some engineering
principles right you you're trying to separate uh uh concerns here okay so so typically it's not
done that way and in fact today's implementation of a concept per are are still suffering from a
lot of legacy uh and so they don't really even have... They're built not just in the front end,
but using really old technology in the front end,
in most cases, with a few exceptions.
So you'll find that it's not as performant
as you might hope for.
They'll improve over time, but it'll take a while.
Okay.
We can talk about that later,
if you want to talk about...
I mentioned this in the C++ Now talk
I gave a few weeks ago.
Right.
We will get back to that.
Okay.
Next article we have is an update from the Visual Studio blog.
And this one is all about updates to their Linux support.
So one thing is that you can now directly target the Windows subsystem for Linux.
And I think they have a full blog post just talking about that.
But then they also have announced that they have built-in support for using the address
sanitizer, ASAN.
And you can now separate your build and debug targets.
So you can build on one Linux machine and then debug it on some embedded machine, for
instance, for example.
Well, Visual Studio is going to be used for everything,
or at least they want us to use it for everything.
That certainly seems to be the goal.
Yeah.
Okay.
And then next thing we have is ENTT version three is out.
And I don't think I've ever heard about this library before,
but it seems to be pretty popular.
It's used by Minecraft and the ArcGIS SDK and several other games.
And it's an entity component system,
which I think we've maybe heard about a couple times in the show
when talking about with game developers using that type of pattern.
Yeah.
And I think I just realized it's that entity.
Entity.
Entity.
Ah, yeah. That's what they did there. Clever, clever. I just realized it's that entity entity clever clever yeah but they
announced a couple changes
they have C++ 17 support
and some built in
reflection
and they made some memory optimizations
is there anything else you want to point out
with this one Jason?
I don't know there's nothing that I need to add to this one.
Okay. And then last thing is announcing C++ Now 2020,
which did they give us the actual date for this in the announcement
or just saying that there's going to be a C++ Now 2020?
I don't see a date. Oh, wait, no. May 3rd to 8th, 2020.
Yes.
But they're also announcing all the best session winners from the 2019 conference.
And it seems like Connor Hoxtra, who we had about a year ago talking about competitive coding, I believe, seems like really run the table.
He won almost every single award.
Really?
Yeah.
Yeah. Yeah.
That's yeah.
That's pretty crazy.
Best presentation,
best speaker,
best news speaker,
most educational,
most engaging.
Yeah.
The only one he didn't get was most inspiring,
which went to,
uh,
David Sankal,
who just had on.
And unfortunately,
I don't believe the keynotes are eligible for awards.
Oh,
okay.
Did you get a chance to, I'm sorry. Do you get a chance to go to Conor's presentation, David?
Actually, I didn't, but I met him there,
and I can totally believe that he would do really well
because he's an engaging person just in a person-to-person situation.
And when we went out for dinner a few times with him in groups,
I think he was really great.
So I can imagine he'd be a great speaker yeah it's always like super disappointing
at c++ now when you you went to all the sessions that you thought you wanted to go to and then you
find out that one session won like 10 awards and it wasn't the one that you chose to go to
you're like yeah yeah when i when i saw the awards, I was like, gosh,
I should have made an extra effort.
One of the things
that's exciting
when you go to
this conference
is you meet
like-minded people
and I promise myself
to go to various talks
but then I get stuck
in a really great
conversation
or even a session
where we're coding
so I spend some time
with one person
working on
basically
doing concept
for stuff and working out the new reflection APIs I spent some time with one person working on basically doing concept per staff
and working out the new reflection APIs and trying to implement some of that.
And I got so into it that I forgot to go to two, three consecutive talks.
I spent most of my time actually in hallways chatting with people
and trying to get things to work.
But it's a great venue and the people there are knowledgeable.
They're excited about what they're doing.
It's a very inspiring conference, I think.
Have you been before?
I went in 2012.
I think that was the first edition that was C++ Now as opposed to Boost.com
for a keynote on modules.
Okay.
Oh, okay.
And Jason, you had some other conference news?
Yeah, we've been remiss talking about some of these things,
but I believe, I mean, let's see,
CppCon's call for submissions just ended.
Right.
But they now have their call for volunteers out,
so that needs to be checked out.
And Meeting C++ 2019, do they currently still have their call for submissions open?
Let's see.
That opened April 24th.
April 24th?
Yes.
Oh, you're able to edit until June 10th.
When does it actually close?
Might be June 10th.
But there's that. I mean, there's just like
so many conference things
happening right now. We've done a terrible
job of actually announcing
when all of the calls for submissions and that
kind of thing were going on, right?
It's harder to do because there's just so many now.
Yeah, but we should be better about it.
So of the things that I know
people need to check out right now is the call for volunteers
for CppCon.
Absolutely.
You're going to try to make it to CppCon this year, David?
You know, I've never been to a CppCon.
I've been asked to attend, but we're a small company and there's so much work.
Even for C++ now, I wanted to go all week, but I had to come back early.
So I think I won't go this year, but I'm hoping to go some year.
I certainly have the green light for my employer.
They let me go.
I got an email this week saying, would you like to go?
I said, yeah, I'd like to go, but here's the thing we have to do between now and then.
And my family does want me a little bit around also.
There's that.
Considering it's like a 20-minute drive from my house,
I'm morally obligated to be there, I think.
Oh, right.
It's in Colorado this year, right?
Yes.
All right.
But I'm really glad to see so much activity in the community.
There's conferences everywhere.
Russia, Australia, New Zealand, South Africa.
Oh yeah, that reminds me. CodeDive currently
has their call for submissions open as well.
That's Poland,
Wrocław, November.
It's certainly great to see all these C++ conferences
spring up just all over the world.
Yeah.
Little by little, some of these people
trickle into the committee process.
Not necessarily in person, but we get submissions and proposals,
participation in the reflectors.
I really feel like the community has gotten broader than it used to be.
Yeah, very good.
So I was just recently doing some research on the history of various features
in C++11 or whatever, and I know I saw your name on many papers that came up,
but if you could just broadly give our listeners
an overview of what papers in the development of C++11,
maybe 14, 17, whatever,
whatever you would like to highlight
that you have been involved in.
Oh, I probably don't remember it all.
And also the evolution process of the language has changed over time.
Like I remember in the beginning days of C++ OX,
the way it worked is that we all got into a room
and we just brainstormed who wants what feature.
And we put all the lists on the board,
and then over the next few days, we'd sketch out how it would work.
So things like decltype, auto,
a number of the smaller features in C++11 were designed that way.
And so my name might be on it,
but it's really sort of a collective effort.
One of them that I'm, it's a very small thing I did,
but I'm perhaps most proud of in C++,
is I wrote the wording needed to allow you to put two angle brackets
next to each other
without a space in between.
I don't know if you ever programmed
with C++ without that.
Yes.
But it used to be
you had to put that space there.
And the reason why is that
it doesn't really fit
in the clean compiler structure
to treat two angle brackets as
sometimes a single token and sometimes two tokens.
So we call it the Lexer hack.
And since the mid-90s, the committee had
talked about, well, we should mandate
the Lexer hack. But
it didn't really fit in the specification. How do you specify
such a thing? And so I
wrote the specification. It's not very long.
But what I liked the best about it,
and so did the core group who reviewed it, is that I made it look very innocuous in the working paper.
So instead of describing a big hack somewhere in the paper, it says, similarly, if this happens, you just read as two tokens.
And it doesn't really say very much about how you do that, but it's clear enough that it worked.
And it has a huge impact in day-to-day life,
in day-to-day programming,
perhaps more so than some of the bigger features I've worked on.
An interesting one that I've...
I actually started the modules work in the committee.
Oh, wow.
So the first iterations of that paper were from me,
and then Doug Greger,
which I assume you know,
Doug contributed a lot of features to C++11,
including variadic templates,
and the first template concepts.
So he took over and brought that to Clang.
So the Clang modules are an outgrowth
of his early work in Clang to try to implement modules.
And then Gabriel Desreis, Gabby,
took over from Doug when Doug went to work on Swift.
And Richard Smith, the editor, also participated heavily in that.
But that whole process actually came out of a reflection proposal that I made.
So there is a paper, I don't remember the number,
but it proposed a complete framework for something like Consexpo functions, but it was called Metacode functions, a reflection library, and an actual metaprogramming library.
It was just a slide, it was not really a paper, I mean, it's a PDF document that you can find on wt21.link. But I was implementing all that stuff and
designing it, and I was thinking to myself,
oh my gosh, all this stuff has to go in header
files. These header files are going to be huge
with reflection code. I need some way
to package that. We can't just keep on
working the way we're doing.
And so I ended up saying, well, I'll just
design modules for that. And so I made a separate
proposal for modules. Now, meanwhile,
modules are in the language, but we're still working on reflection uh gabby did get this
concept for those so we're we got that part done are you involved in the current reflection
proposals yes yes uh in fact um there are two competing proposals at this point. One is ours, is paper P1240.
So if you go to wg21.link
slash P1240,
you'll get an early draft of our
proposal. And I do that work
with Andrew Sutton, who is the person who got us
concepts in the language.
And also Faisal Vali,
who is the person who got us generic
lambdas and constexpr lambdas in language.
And it's a fairly fleshed out proposal
with an implementation,
actually almost two implementations at this point.
The other proposal is by David Sankel,
Alex Noman, and Matusz Czoczlik.
You had David a few weeks ago on.
And that proposal, it's more of a sort of a,
it's a little bit, I don't know how to describe it.
It's based on the TS.
It's sort of a translation of the TS.
How would I take the TS as it is and translate it to the call sex per world?
And it's more, so it says, here's how you would do that.
It doesn't actually give a full API or anything like that.
And so I don't think there's any implementation so far.
But they're competing.
They're a little bit different in their approach and sort of the scope of what they're trying to do.
And that's off the table for C++20 probably, right?
Yeah, it's not even clear we will have it for C++23 at this point.
Really?
I don't think many of our listeners, they didn't want to hear that.
You can just say that.
Well, you know, we're still aiming for that, right?
And certainly the direction group,
I think is unanimous that this is something
we should pursue.
But from my experience, you know,
when you have competing proposals,
there's going to be some time needed
to flesh out how, you know,
how we're going to merge them or which one we'll take.
That takes some time.
And when you're done with that, there's still quite a bit of work needed to just make it really robust and have a spec that you can rely on.
If you think about how long modules took, which also had competing proposals, or how long concepts took, also competing proposals, they were both 15 years and more.
So, you know, we'll see.
I've never heard anyone quite put it that way,
that it was more than 15 years in total.
I think my original modules paper was 2004.
Right, that's not on schedule, yeah.
And we just put them in 2019 so that's 15 years yeah and uh when was the original uh concepts proposal do you know
that's been a long time going well well concepts were already described in the design and evolution
of sleeper plus the the book of bianni which was published in 1994. Okay. So I'm not sure if that counts as a paper, but it certainly,
and he had been thinking about it before.
I think, in fact, you know what, the first paper describing templates
was actually a conference paper in 87,
and I believe it already had a little bit of a sketch for a concepts-like feature.
Okay, so now I have, since you just said you knew like exactly when that
paper was published or whatever like i when i was doing my research into the history of c++
recently i had a hard time finding specific papers pre-c++ 11 is that all publicly available
information for people who are curious uh it's probably publicly available but it's not necessarily
available online. Okay.
You have to,
you have to go to,
you know,
university libraries and so on.
Oh,
and get back when they actually used to print these things out before
standards meetings.
That's right.
Yeah.
Yeah.
I have a,
I don't know if I still have,
I probably have somewhere at home still one or two mailings,
which are these literally stacks of paper.
When the mailman brought it,
he couldn't fit it in a mailbox,
he would have to ring,
and it was quite something.
And also, you'd go to proceedings
like the templates paper
where Bjarne proposed templates at first
was USENIX conference in Colorado.
So if you go to the proceedings
of the UNIX conference of 1987,
you would probably find that paper.
Okay.
I am interested in that.
I don't know if I'm that interested to do that much digging.
You could try to send a mail to Bjorn and see if you can get a copy.
I'm not sure if he has a copy handily available.
Right.
It would be a possibility.
Right.
Okay, so of all the things
that you've been involved in
that have now been accepted
in the language,
do you have,
I want to ask
if you have any regrets.
Is there anything
that you would have done differently
in hindsight?
Yeah, probably.
Now,
I have regrets about certain things where I don't necessarily regret the choices i well first
i have to confess something when i first came to the committee uh the export wars raged on so
people were fighting about uh where the templates should be you should be able to instantiate a
template in another translation unit from a current translation unit and that there was a feature called export to templates that came out of that in c++ 98 and the fights about that or the discussions
were very active when i first started attending the committee and i was i was a young student
and i thought it was very exciting all these people saying great things and that feature
just looked awesome to me and so so i i supported it all right. And so I regret having supported it.
But as karma would have it, I had to implement
it years later. So I think justice, I've paid my
dues for that mistake. I'm not
very happy with class template argument deduction. And I did
participate in that.
My experience and I started off with a proposal for that.
And that proposal was terrible.
I did a poor job thinking it through.
But the core working group immediately found the problems with it.
And Richard Smith then came up with this great idea of deduction guides, right? So you're probably familiar with C++17 deduction guides, which are
function-like things that describe how you should deduce something from an initializer.
And that is just an awesome way of thinking about it. And I love deduction guides.
But then a couple of things were added on top of that. One is that you sort of have implicit
deduction guides. And I personally think those are
a mistake. And also, we
made a special case for
the singleton case.
So if you
say a vector v
and you say
equals braces and a single element in there,
that's treated differently than if you have
zero, two, or more elements.
I really think that's unfortunate because it makes generic code just, you know, basically class-centered argument deduction or CTAD.
You have to be careful when you deal with generic code, especially with things like what you call pack expansions, right?
So you have an initializer that has a pack expansion in it.
That might not do what you think it will with CTAD.
So what,
actually,
I'm not familiar with that issue.
What happens if you do
pass a single element
to a vector
expecting CTAD?
Well,
it will prefer
treating it as a copy
rather than as
a single element
for the vector.
So instead of,
say you have
a vector V equals
open brace,
an element that's typed vector event
close brace.
It will see that as an attempt to copy vector
event, and so deduce the other thing also as vector
event, instead of making it a vector of
vector events.
And so that decision was made
because the expectation is that most of the time
when you write that kind of code,
what you intend is a copy. And perhaps that's true, but because it's
no longer, because it's a special case, now you can no longer do this
thing generically. If you put two Vs in there,
then suddenly it does become a vector of vectors.
Okay. Okay. I want to interrupt the discussion for just a moment to bring your word from our sponsors. PVS Studio is a tool for detecting bugs and security weaknesses in the source code of programs written in C, C++, C Sharp, and Java.
It works under 64-bit systems in Windows, Linux, and Mac OS environments, and can analyze source code intended for 32-bit, 64-bit, and embedded ARM platforms.
The PVS Studio team writes a large number of articles on the analysis of well-known open-source projects.
These articles can be a great source of inspiration
to improve your programming practices.
By studying the error patterns,
you can improve your company's coding standards
as well as adopt good programming practices
which protect from typical errors.
For example, you can stop being greedy on parentheses
when writing complex expressions
involving ternary operators.
Subscribe to Facebook, Telegram, or Twitter to be informed about all publications
by the PVS Studio team. Links are given in the podcast show notes for this episode.
So you recently
gave a keynote at C++ Now about C++
constants. Could you tell us a little bit about your keynote talk?
Right. So I've been very involved lately
in extending the capabilities
of constexpr in the language.
The reason why I've done that is that
two years ago, I
came to the group that does reflection
and I asked them to change direction
because the direction they were
going, which is the direction you'll find in TS,
is that they represent everything using types
and rely on template
metaprogramming to do things. Now, the problem
with that is it doesn't scale
well at all. If you don't have the metaprogramming,
you know that large programs just are
very slow to compile and run out of memory.
We can talk later about that if you're interested.
So I came
and I said, well, we should use constexpr instead
and we should compute those actual values
using code that looks just like C++.
It'll be more efficient, and it'll be easier.
And the group agreed with that, and so we changed direction.
But when I presented that, I also said,
well, we don't actually have the tools we need to be able to do that.
We'll want dynamic allocations.
We'll want functions that are guaranteed to be evaluated at compile time
because we're doing compile time reflection.
It'd be bad if suddenly you try to access your compile compile time because we're doing compile time reflection.
It'd be bad if suddenly you try to access your compile internals while you're running programming.
It's just not possible.
Stuff like that.
So in order to front load that work
and not having to put everything in the reflection group,
I started separately designing those features.
And they're now mostly accepted,
except for the dynamic allocation part.
So the organizer of C++ Now thought that
since I'd done that,
I'd be a good person to talk about
constant expert evaluation in general.
And so I prepared this talk
that has sort of three parts to it.
One is give a general background
of what's the mental model to think of when you think of
constant evaluation in C++, right? So what are the basic principles that the language uses,
and we should guide the evolution of the language going forward. Then the second was an overview of
what we can do in C++ 20, what we will be able to do in C++ 20. And the third one was actually an analysis of the performance of consistent evaluation today.
And you might be familiar with the abstraction penalty.
That was a term that Alex Stepanov introduced in the mid to late 90s, 97.
He found out that when you compile code like the STL, you know, STL was supposed to be as performant as handwritten code
and it was only true
for very simple types.
He found out that
when you started composing things,
you had to pay
an extraction penalty
because the compiler
couldn't optimize
all the way through.
Now,
compilers have improved
to most of the time.
You know,
if you,
you know,
if you say
have a vector of doubles
and you iterate
with a pointer
or you iterate
over it
with a more abstract iterator
and instead of a double you have a class containing a double, Compile will nowadays
usually see through that and give you exactly the same code at high optimization levels.
The problem with constexpr is that optimization and running are both in the same budget. It's
in your compile time budget. So there is no such thing as a zero abstraction penalty.
Every time you add a little
abstraction in your code, right, in your context for code, you'll have to pay for it. But what's
surprising is just how much you have to pay for it in current implementations. So we looked a
little bit at some of these things. So I heard on Twitter that that same kind of question came up
in Hannah's keynote with her compile time
regular expressions about performance at compile time. So what hope do you see for that?
Well, as I mentioned earlier, when we started talking about constexpr,
compiles are just trying to keep up with the language. And so they implement stuff
as quickly as they can within the framework that they have.
So we've had a certain way of evaluating constants for 25 years, and suddenly comes
constexpr, and we're asked to do it differently. So certainly, G++ and Microsoft and our front end
at first just implemented on top of this old machinery, which was not at all meant to scale
that well.
I think we'll little by little refactor those things,
re-engineer those things, and improve the performance.
In my company, we've already done one important step towards that.
So now we're like orders of magnitude faster. But I think there's still one or two orders of magnitude speed
that's on the table that we'll probably get.
It's possible that we'll probably get. So is it possible?
It's possible that we'll get even optimizations,
like sort of the kind of stuff
that people do with interpreted languages,
but it's a little trickier for the C++.
I mean, C++ is not a language designed to be interpreted.
So we'll see how that evolves.
But I think we'll see things getting better.
They might get a little worse first
as people add the other constexpr features,
things like we'll see in C++20
add a little bit of a cost
to the implementation.
One of the things you'll be able to do is
have constexpr destructors, and that's
probably a feature that you'll have to pay for even
if you don't use it.
But it'll improve after that, I think.
So, just to be clear, constexpr
destructors, not in C++20,
but you see that probably coming.
No, no, no, they will be in C++20 if all goes well.
They're part of the dynamic allocation proposal
because we'll be able to have vectors and strings in constexpr.
So obviously the destructors have to be able to deallocate memory
so that they'll probably be there.
But the implementation of that is surprisingly difficult.
Okay.
When I was just at Course Evils Plus, someone made a comment.
I do not remember who it was.
Not that I would necessarily say if I did.
They saw a hypothetical future of constexpr actually being compiled
to as in JS or something and then being run in
a virtual machine and then taking that result back out is that i it's possible that we'll get
something like that but i'm not sure the balance of cost versus benefit will ever will ever reach
there and that's that's a tricky part right as you know we have one budget with a compiled with
compiled budget how much
time do we want to spend just translating these functions into other formats and and then running
another optimizer on that and another back end so i'm not sure we'll we'll have to experiment and
find out um it's possible that like a javascript engine there will actually be several engines in
a single product where you you know as long as it's not too hot, you'll use
a cheap to translate but slow to
execute engine and then if it
starts, the compiler starts
discovering that
you're running something a lot, it will
optimize that to another engine.
Again, the problem here is most
compiler teams are relatively
small. We're just five people here in my
company.
How much resource can you allocate to that while the language moves forward in other areas?
That is something that has struck me recently, is if you sum up the number of people who are
involved in standard library implementations and compiler implementations, I mean, it's great that
we've got three, four different competing
implementations of the compilers, because then we get to prove that these things are correct.
But the actual total number of people involved in this around the world is shockingly few.
It is, it really is few. And some of the lesser known compilers have amazingly efficient teams.
I know of one C++ frontend, which is, I believe is now fully conformed to C++ 14,
has one person developing it part-time. Wow. That is really impressive. That's a person who
earns their wages, I guess. I hope so. He comes to committee meetings. He's not particularly vocal,
but he knows his stuff. And obviously, he does fantastic particularly vocal, but he's, you know, he knows his stuff.
And obviously, he does fantastic work.
Wow. Apparently.
So going back to your keynote, you said the second part was on const eval and how we'd
be using it in C++20, I think. Do you want to go into that a little bit more?
Sure, I'll try to remember. It was basically going over
all the ways we've relaxed
and improved constexpr
since it came in. So in C++14,
we just did one big change, which was
instead of just having
a return statement in your constexpr functions,
you could now have generally general
functions. You could have loops,
variables, and so on. So that was a big change.
Then C++17 added constexpr lambdas
and made a change also with respect to template arguments.
And C++20 will bring you a whole bunch of new stuff.
One is constval function.
So a constval function is like a constexpr function,
but it has to produce a constant.
If you don't get a constant, it will get you an error.
So you won't get in a situation where you think that you wrote code that costs
you nothing because it's compiled at compile
time, but in fact the compiler didn't
evaluate as a constant.
This will avoid that
problem. There is
an interesting new library
function called isConstantEvaluated.
It's actually a little tricky,
but the way it works is, say you have
a function that does real tricky stuff to works is, say you have a function
that does real tricky stuff to get the best performance you can at runtime. Maybe it runs
inline assembly. You can't have this constexpr. Now, you know of an algorithm that you could
write using regular for loops and so on that would be constexpr compatible, but it wouldn't
optimize as well. Well, you can put an if statement that says well
if you're if you're trying to evaluate this in a in a context where you need a constant then just
use this this for loop you know it's slower but it's done at compile time so you won't pay for
the runtime but if if you're actually generating a runtime code then use this other thing use this
this tuned code that i have um and we among among other things, wanted that to implement,
to make string and vector
available in constexpr evaluation.
But I think it's generally useful
to a lot of people.
Let's see, what else do we have?
We've changed some rules about unions, so you can
change an active member of a union
during constexpr evaluation.
I'm probably
forgetting a few more.
But yeah, so quite a few extensions,
of course, and the dynamic allocation.
So you'll be able to dynamically allocate memory
during constexpr evaluation,
but you have to make sure everything is deallocated
by the time you're done with the computation.
So leak is undefined behavior.
It's not undefined behavior.
It will make it non-constant.
So you'll get an error.
Well, it basically says,
sorry, that is not a constant.
Okay.
And if you try to do that
in a context where you need a constant,
you'll get an error.
And my implementation says,
you know, it's an error.
You didn't deallocate everything.
Here's the first allocation
that didn't deallocate,
that wasn't deallocated.
So it's very easy to track down. We actually had a scheme where you'd be able to allocate you didn't deallocate everything. Here's the first allocation that didn't deallocate, that wasn't deallocated.
So it's very easy to track down.
We actually had a scheme where you'd be able to allocate,
to have memory that's left over,
and we would then promote the dynamically allocated memory to either file scope memory,
to a static allocation or automatic allocation.
So you could do something like a constexpr vector event
and have something
computed at compile time
and now you would have that vector
actually be statically allocated
in your program.
Unfortunately, we ran into
some problems with that
late last year.
We found a solution for it,
but the committee didn't love the solution.
So we're going to wait
until after C++20
to get that into the language.
So C++20, you have dynamic allocation,
but you have to clear it all up
before you're done with the computation.
Hopefully, we'll have dynamic allocation.
Are you promising it?
I can't promise it, but I have high hopes.
And I'll be sorely disappointed if we don't have it.
Okay.
Are you going to make it to the next C++ Committee meeting?
Yes.
I've been attending since 96,
and I think I've missed something like three meetings.
Oh, wow.
Wow.
All right, so you were involved in the original modules proposal,
you said, right?
Mm-hmm.
And you're doing all this work on const expressions
and const eval right now.
And something I've been thinking about a lot lately is
if we're doing more things at compile
time that can be done at compile time,
it seems to necessitate
more things living in header
files.
Yeah.
What's that?
I had the same thought. That's why I started
modules.
But it doesn't seem like
modules helps that, right?
Because we still have to have the definitions available in the header files for the things that are consuming the modules for the constant expressions.
Or am I missing something?
Right.
No, I think you are missing.
You can put the context for definition in the module, in the module interface file, as it's called, and it will be pre-compiled.
And then we'll just import the definitions as we need them.
So we can have header-only libraries
that will benefit from modules effectively.
Absolutely.
So instead of being header-only,
they will be module interface only.
But it's the same ID except it's pre-compiled
and therefore it's faster to build.
Oh, then I was absolutely missing something there.
Now I am looking forward to modules
more than I was an hour ago.
It's the same with inline functions.
Your inline functions can go there
and you'll get the benefits of easy inlining
without relying on link time optimization, LTO.
And yet they're sort of pre-compiled.
Pre-compiled in the front-end sense.
The back-end still has to
we'll still have to spend time optimizing everything you use
do you think that that would then change
the way that we write programs
maybe we don't use header file
or you know CPP file separation
at all anymore we just
throw it all at the module and let the compiler do the right thing
the public interface that is
I'm not sure
I still think it's nice to have a clean and let the compiler do the right thing? The public interface, that is. I'm not sure.
Okay.
I still think it's nice to have a clean binary separation for engineering purposes.
So I think we will still have.cpp.
I do hope that header files will slowly disappear,
but they will never really disappear.
We have too much of a legacy.
But here's an interesting thing I've been thinking about.
So right now we have, you know, talking about modules. There's a lot of talk about how are
we going to integrate that in our build systems, right? So right now our build systems are a kind
of computation that happens outside of your compiler, right? So using your tools, we're
using make files, Ninja, whatever you like to use, and your scripts and so on but it's a lot of different different tools not standardized i find that very often when i get into a project you know i try to
participate in it the problem is not learning the source code the problem is learning the build
environment i spend way more time on that than anything else well we're currently also looking
at um and this is this looking much much more ahead but we're looking at things like side
effects in constexpr.
How about being able to read some files
so you can process them and generate some static data for yourself?
Or how about being able to write some files?
I'm fully on board with the reading,
but the writing I'm still not sure about.
Well, I implemented a few weeks ago in my compiler
a way to do some output,
and it's really nice because if you
want to debug your constexpr functions,
that's a great tool to have.
But what if
your build itself could be a
constexpr evaluation? So instead of
having these external tools,
you would have a CPP file
that imports a build
tool library, and you would
describe using
brace initializers or functions, however that imports a build to a library, and you would describe using, you know,
brace initializers or functions,
however things are built,
and you just say, compile this,
that would kick off compiles of other things,
because constexpr would give you access to the compiler.
Right.
And off we go.
Everything is within the language now,
including your build process.
Do you see a future where that happens?
I am gunning for a future where that happens.
So you've been on the committee since 1996 and you're not tired of it yet, in other words.
I love this. I love my work.
I enjoy the language.
The people in this community I find are generally friendly and they're always super interesting.
The company I work for is a dream job.
So yeah, I didn't think this was where I was going to land
because I actually studied in numerics.
I thought I was going to design rockets or something.
But I don't regret it. I love this work.
I was just for some reason expecting you to say that your degree was in horticulture or something
and you just landed into this that would that would be really cool but no yeah that would
actually be awesome you should change your backstory and it's fine my wife is really good
with plants she has a she has a green thumb but I don't think I can steal her thumbs, though.
Okay. I guess before we let you go, you've talked so much
about the history of different features
you've worked on. Is there anything
you would like to do? Like, if you had a magic wand,
something you would change, some feature to add
or take away? Yeah, for sure.
I already talked about something I don't
like about class template argument deduction.
Sure. I wish I could change the way we do initializers a little bit.
I would definitely like a linear declaration model for just general declaration syntax.
I have no idea what you mean.
Well, so we inherit from C this bizarre way of composing declarations, right?
Okay.
If you want a pointer to a function
that returns a pointer to something else it's really hard to teach it to teach that to someone
right it'd be so much nicer if you could just write pointer to this to this to this you can
write left to right and read it out it's not hard to do right it's not hard to design a language
that's done but somehow that's not what we have i'd love to i'd love to change that and specifically you would like to
read it left to right not right to left i'm just making a east coast east const west const
i'm actually an i'm an east const mostly but const experts will mention that
um but uh but but yeah i would make it left to right if I had a choice. Another thing would be, arrays would be value types
instead of that weird in-between thing that we have.
Right.
Yeah, but all of these things you only get through engineering
and being successful.
We have to live with the mistakes we made.
Vector bool is another one.
That's like the butt of
every joke and c++ and of course there's vector of bull well we have tons of those things right
because we're successful we've experimented and most of our experiments are great a few fail
and a few don't really fail they just they have some quirks that we have to learn to live with
okay well it's great having you on the show today, David.
Well, thanks for having me.
I had a great time.
Thanks for joining us, yeah.
And great to meet you guys.
Never met you before.
We should meet somewhere in some conference someday.
Yeah, all right.
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
at cppcast.com
Theme music for
this episode was provided by podcastthemes.com