CppCast - C++ Epochs
Episode Date: August 29, 2019Rob and Jason are joined by Vittorio Romeo from Bloomberg. They first discuss some changes in the recent Visual Studio update for cross platform linux development, and some post-Cologne ISO developmen...ts. Then Vittorio goes into more detail on his proposal for C++ epochs, which could allow the language to more easily introduce breaking changes in the future. News C++ Cross-Platform Development with VS 2019 16.3 vcpkg, Cmake config, remote headers and WSL Post-Cologne mailing Links Fixing C++ with Epochs C++ 11/14 for C++03 Developers Sponsors Enter #cppcast in the Message field and get a month-license instead of 7-day license PVS-Studio PVS-Studio Twitter
Transcript
Discussion (0)
Thank you. CppCast is also sponsored by CppCon, the annual week-long face-to-face gathering for the entire C++ community.
Come join us in Aurora, Colorado, September 15th to 20th. In this episode, we talk about some VS improvements for Linux development.
Then we talk to Vittorio Romeo from Bloomberg.
Vittorio talks to us about his ideaast, the first podcast for C++ developers by C++ developers.
I'm your host, Rob Irving, joined by my co-host, Jason Turner.
Jason, how's it going today?
I'm okay, Rob. How are you doing?
You know, it's the last week of summer here in North Carolina.
My kids are going back to school next week.
Oh, that kids around here started like two weeks ago, a week and a half ago.
Really? That early? I always thought North Carolinaolina was early compared to new jersey at least i i think our
schools are just underfunded and it's just trying to get in the days where they can or something i
don't know oh man well i was gonna say my kids have chosen to spend their last few days of summer
freedom uh with stomach bugs so they're both sick today unfortunately that's the wrong time of year
for that.
Yeah, I guess there must be something going around. But yeah, hopefully they'll get over it soon and be able to go to school next week.
You didn't take them to a sketchy restaurant last night or anything, did you?
No, I don't think so. I don't think it's food poisoning. I think it's just a stomach bug.
Yeah, I met someone. I saw someone once, a good friend, who was like,
oh yeah, you you know i just had
food poisoning last night but i'm better today large group of us hanging out together the next
day we all had food poisoning uh-huh uh-huh yeah 24-hour stomach bug it was absolutely terrible
it was well i don't know how it's completely unrelated though yeah okay well i've talked
about a piece of feedback we got a
tweet from Adi Shavit who we've
had on the show before and he's the one who runs
the core C++
conference and he wrote
me running listening
to the latest C++ cast where Rob and
Jason are discussing the Dropbox article
about dropping C++
as a common shared mobile dev language
in parentheses for wrong reasons
and then he said my brain the salami method and Rob and Jason the salami method about dropping C++ as a common shared mobile dev language, in parentheses, for wrong reasons.
And then he said, my brain, the salami method.
And Rob and Jason, the salami method,
which we incorrectly referred to as the burrito method for a moment. Yeah, that was totally me.
It's definitely not the burrito method.
Definitely not the burrito method.
And we do have this article from his blog
where he talks all about the salami method.
And I think we talked about it before on the show, and I'll make talked about it before on the show and I'll make sure. At least once.
At least once. And we probably
talked about it with him when we had him on.
I think that's what happened. I think we mentioned
the article and then we talked about it with him later.
Yeah, I'm pretty sure.
That's two years ago that he posted that
article, so we're getting old.
Yeah.
Okay. Well, we'd love to hear your thoughts about the show you can always reach
out to us on facebook twitter or emails at feedback at cbcast.com and don't forget to leave
us a review on itunes or subscribe on youtube joining us again today is vittorio romeo vittorio
has been a software engineer at bloomberg for more than three years working on mission critical
company c++ infrastructure and providing modern C++ training to hundreds of fellow employees.
He began programming around the age of eight and quickly became a C++ enthusiast. Vittorio
created several open-source C++ libraries and games, published many video courses and tutorials,
and actively participates in the ISO C++ standardization process. He's an active
member of the C++ community and has an ardent desire to
share his knowledge and learn from others. When he's not writing code, Vittorio enjoys weight
lifting and fitness-related activities, competitive challenge in computer gaming and sci-fi movies and
TV series. Vittorio, welcome back to the show. Thank you, Rob. Hi, Rob. Hi, Jason. It's been a
while. I think a bunch of years since I came here. Yeah, I was just checking.
You were like episode seven we had you on.
Wow, I was beta testing the CFP cast. Now it's grown quite a bit, and I'm really happy to be back here.
Thank you, guys.
You know, you mentioned sci-fi,
and I feel like a lot of us in the programming world enjoy sci-fi.
And I had a recent class where I'm like,
I always ask my students,
tell me your hobbies and stuff,
because I want to see if I can relate C++
and what we're talking about
back to the things that they do for fun.
And I had no one in like a class of 15
mention sci-fi at all.
And I'm like, are you for real?
That's surprising.
And then one other person was finally like,
oh, well, yeah, actually, I watch sci-fi all the time, but I don't consider that a hobby.
That's just a thing that I do in my spare time.
I'm like...
That's the definition of a hobby.
It kind of sounds like a hobby to me, but I don't know.
Maybe it's just normal, you know?
Like, it's a requirement.
They don't see it as an extra thing.
Perhaps.
I'm just, now that we went through all that, I'm curious, is there anything good you're watching right now?
Not right now, honestly.
I have a list of
things that I watched in the past that I really loved,
like Fringe, for example, was a really
good TV show, and also
an anime called Shinsekai
Yori, which I found on
Steven Lowaway's website, which
is, you know, it has a bunch of reviews
for sci-fi movies and stuff like that.
And on my website, I actually have a list of
shows I watched and I liked.
And to be honest,
I have done a very poor job at keeping it updated.
But
I should go there and add a bunch
of the new stuff I've seen, which
I think is worth sharing.
But right now, not much
sci-fi, unfortunately. Mostly
watching
the Netflix series that are
quite popular, like
House of Cards and House of
Paper and stuff like that. So
I need to get back on track with my sci-fi
passion, honestly.
To be fair, though, when I
look back and look at how many hours of sci-fi
I've watched, it's questionable how I have spent my life.
So there's that part.
If you're out doing things instead, that might be a better use of time.
That's true.
Although I will say, you know, you can definitely do both.
If you're looking for a newer sci-fi series, I watched The Expanse,
which is now on Amazon Prime Video,
and that one was quite good.
Okay.
I feel like there's a reason why I haven't started that.
Yeah.
I've seen that.
It involves, you know,
we've expanded into settlements on like Mars
and in the asteroid belt,
and yeah, it was a good show.
Is it complete?
Like it's over?
There have, I think, been three seasons, it was a, it was a good show. Is it a complete, like it's over? Um,
there,
I think been three seasons and I believe they're working on a fourth.
Okay.
Yeah.
Amazon original series or something.
I think it started on sci-fi and then Amazon picked it up for the third season.
Uh,
I'd have seen reviews.
Yeah.
It's got good reviews.
Some people like complain that once Amazon or Netflix picks up a series,
you really don't know
what's going to happen like they might cancel it for seemingly no reason at all because they don't
they're not driven by the same like ratings and ad revenue kind of things that that uh the major
networks are yeah i mean i think the show and the amazon season of the show was still good yeah okay
anyway back to uh the main topic of the podcast.
We got a couple news articles to discuss, Vittorio.
Please feel free to comment on any of these,
then we'll start talking more about what you've been up to lately, okay?
Sure.
Sounds good.
Okay.
So this first one is on the Visual C++ blog,
and it's C++ cross-platform development with 2019 version 16.3,
VC package, CMake configuration configuration remote headers and wsl and
it's just a summary of some of the improvements that went into the latest version uh covering
some of those things i just mentioned um now they're able to do uh parallel builds with um
with wsl and linux which i thought was a pretty good. Yeah.
Yeah. My mind is just a little blown by this all around because I didn't realize,
first of all, that you could connect to the WSL instance with visual studio, which is
the obvious thing to do. I think that is fairly new. Yeah. Okay. Yeah. That was just added with,
uh, 2019 16.1 it says. Okay. Yeah. So that there that's not that long ago and then being able
to use vc package so you can build one project in visual studio and the way this is written
basically be like i want to build in linux i'm going to use the wsl i want to build in windows
okay you know like you're it's all just right there all in one ide i feel like i have to give
it a chance at some point yeah and and they're talking about some IDE. I feel like I have to give it a chance at some point. Yeah. And they're
talking about some of the like CMake integration with VC package. So when you're, you know,
writing out your CMake, you can write find package open CV. And if it knows you don't have open CV,
it'll prompt you to go and grab it with VC package. It looks like I feel like this level
integration should also work with the way that I use CMake.
And that's something else to test and see how well it all works. I've never, excuse me, CMake.
We're talking about CMake here.
I meant Conan.
It would be interesting to see how Conan does also integrate with WSL and stuff,
which I've never tried.
Anything else specific you wanted to call out here?
I don't really use Windows much for development. And if I do, I'm kind of stuck with MinGW and MSys2.
They kind of do the job quite well.
I'm really happy to see the direction
Microsoft is going with WSL
and bridging together the world of Windows and Linux
and giving people more options.
And what I can say about Visual Studio
is that I've used it in the past for C Sharp
developments, and it's just an amazing
tool, so convenient to use,
so nice to be able to have
interactive debugging and stuff like that.
And if it gets very, very nice
integration with both CMake and WSL,
I can probably see myself trying it out again
in the future if I can keep my
Unix-like workflow all the way through.
That would be really nice.
It looks like they're definitely heading down that path
where they would be able to support that.
I'll sometimes have students ask me,
well, how do you use GDB in this really difficult debugging situation?
And I'll be like, well, I've already told you
that all my projects are class platforms,
so if I have a really hard debugging problem,
I just open it up in Visual studio it's that debugger yeah okay and then next article we have is uh this from arthur dwyer's blog and
it's covering the post clone mailing um and it's first going over a couple uh items that were in
the post clone that he identified some of which he worked on like um adding more implicit moves
which look like they're going to be making it into c++ 20 right yeah yep and then he also um
and we talked to arthur earlier this year and uh he's very opinionated about not being a huge fan
of the three-year release cycle and he does spend spend a bit of this blog post kind of reiterating that,
hoping for like a five-year release cycle.
But I don't think that's going to change anytime soon.
I got hung up on the features and didn't even get down to the question about the release stuff.
Because this one, more implicit moves.
Sure.
Like, oh, and by the way, there's more implicit moves.
And you're like, no, wait, wait, wait, what? Like, I have to make some notes real quick, because I need to change
a couple of conference talks that I'm giving in a week, you know, to cover these possibilities.
Like, I didn't see that coming. And I still don't know the full implications of it. Because as he
says, there's no prior art for it. So clearly, no compilers implement it currently. And he did say
that's the case with some of them. But with some of the implicit moves that he was first recommending,
he says some compilers were already kind of doing this under the covers, right?
Yeah. And for the sake of our listeners, this is throwing an R value reference.
And also returning an R value reference.
I think but returning an rvalue reference,
that's what's new, right?
That's the thing that he says there's no prior art for.
Yes.
Are you saying that some compilers
used to move when throwing?
Yeah, that's what he's saying here.
Oh, no, sorry, not move when throwing.
It was move when throwing a value,
not move when throwing an rvalue reference.
That's the prior art part, yeah.
And now the surprising part is if it's an R value reference
and you return that, then that's an implicit move.
Yeah.
And I really want to know what does that mean
if it's an R value reference structured binding,
which is an R value reference into a temporary thing
that was hidden object.
I mean, like, is that an implicit move or not?
An R value reference from a sub member of
an of a of a structured binding return my mental model for a structured binding is that the names
you provide in the square brackets are like aliases for the existing things they're not really
references even though they act like them so yes but if i explicitly said auto ampersand ampersand
and then gave the structured binding...
But then the reference would be the object that you're destructuring,
not the actual names.
Yes.
So you would say, if you return one of the pieces,
are you expecting it to be moved? Is that what you're saying?
That's what I am asking, yes.
Okay, yeah, that's interesting.
We should see what the wording says wording says yes i'm gonna have to
go and read the wording and i'm gonna have to figure it out usually this kind of thing i like
to just test and see what the compiler does and call it couldn't but you know what happens when
you do that gcc and clang are gonna do something different and then you're gonna have to see the
warning again yeah but usually gcc and Clang agree on that kind of thing.
Usually.
Usually.
Most of the time.
Was there any other of the actual papers he's highlighting that either of you wanted to talk more about?
I want to say the implicit move from rvalue reference, in my opinion, is really, really important.
This has been something that when I teach classes at Bloomberg and also in general when I'm telling people about R values, they get really
surprised when you have an R by reference
and it becomes a copy
when you return it because
mentally it's an R by reference, it's something you could
consume, so why isn't the return
consuming the actual thing? So I think
this will make teaching R values
a little bit simpler as it removes
this kind of edge case
which you need to explain to people why it doesn't move.
That's nice.
Regarding the other things,
I see that Arthur is like,
I'm not sure if it's the right word,
but maybe conservative in the sense that
he has some really good points about potential dangers
of proposals that were accepted or not.
For example, there's a polymorphic allocator one and the entity piece one,
which is basically allowing things like strings as template arguments.
There are some cases and situations where they don't work in a very,
I would say, not in a perfect way.
However, there's a risk here on both sides, right?
There's something that Bjarne always says
during committee meetings,
which is basically,
perfect is the enemy of good.
We need to be able, you know,
to move forward and give people what they want.
An example of a very good use case of NTTPs
is Hanna Dusikova's compile-time rejects.
That would not be possible
without the proposal that was accepted.
On the other hand,
you know, it's really hard to figure out what the line is, whether, you know, it's good enough,
or it's good, but it puts us into a corner where we cannot fix some underlying issues later. So
I think these papers need to be considered very, very carefully. But also, you know,
if it's just something which is a tiny problem or some edge case,
which is not likely to happen during real code,
I would prefer not to see these features delayed
because right now, like today,
there are libraries that could be using these features
and be really, really powerful and good
for the C++ ecosystem.
So we need to be careful in both directions, in my opinion.
Right.
If you don't mind, I'd like to go back to what you said
about R-value reference implicit moves.
You said that'll make teaching it easier,
but I have to ask, at Bloomberg,
or at least in the people that you teach,
will they be able to use C++20 as soon as it is released?
The situation at Bloomberg is quite
interesting in the sense that
pretty much every team
has a lot of independence
in the way they decide to work
not just regarding
compiler versions but even languages
usually everybody tries
to be
to conform to the same compilers
and target the same architectures.
We do have some legacy architectures
that prevent us from moving to even C++11,
so some teams are still stacked on O3,
but most of the teams that just target Linux
can basically decide whether to stay with the official compiler,
which supports 14,
or experiment and just use latest version GDC or another
language or whatever. So there's definitely going to be
some people that maybe don't have
safety critical
systems that might
jump on to C++ 20 as soon as it's out.
I can definitely see that happening.
And some people that will have to wait
until it's been battle tested
and until
there is official support for it so it's more of
a mixed uh mixed scenario there but i i definitely believe some people will jump on it and in general
what we try to do when training is also preparing people for the future we our expectation is that
eventually even if it takes a long time they are going to have exposure to these new technologies.
And even if it's not inside Bloomberg,
just as part of their daily contribution to the Salesforce community,
or if they want to participate in standardization,
it's good to have them know what's coming
and how they should prepare themselves
and what they can work for
if they decide to participate in easo and stuff like that
so i would definitely teach this in my classes with a caveat obviously that is just in 20
but it's always i'm very confident it's gonna be like um very nice to hear for the students that
all these weird edge cases are being worked on like like there is hope for the future.
And, you know, people know what they're doing, and we're trying to make the language easier to use and more consistent within itself.
So that would also encourage people to stay with C++ and not say, oh, man, I have to remember
all these edge cases.
Knowing that it's being worked on is a good thing.
Yeah, I appreciate that perspective.
Because, yeah, I mean, sometimes I'm in classes and I'm teaching, it sounds like, similar experience where you have different teams and some of them can only use 11, some of them are up to 14, some of them are up to 17.
And you're like, well, this is what you can do.
You can't do this yet.
You can do that now.
And, yeah.
So I see the point, though, of giving them hope for the future.
Okay. So Vittorio, we talked about a recent blog post
you wrote just a few weeks ago about fixing C++ with epochs. Can we start off by going over that
proposal in a little more detail? Yeah, absolutely. So this started basically from a feature that the language Rust has, which is called Editions.
And the idea is that in Rust, they wanted to have some sort of way to perform backwards
incompatible changes, but still allow people to use code from the past, like seamlessly
with new code.
And the way they did that is basically every module you write, so every
source file you write, rather every library, has something called an edition, which right now can
be either 2015, 2018. And between editions, the syntax of the language can change. For example,
in 2015 edition, there was little to no syntax to represent a dynamically polymorphic object,
which was a little bit, you know, dangerous, because you could represent a dynamically polymorphic object, which was a little bit, you know, dangerous
because you could start making these polymorphic objects in your code
that's not really obvious to the reader where they are.
And in 2018, they added something called dyn, the dyn keyword,
which makes it obvious that the polymorphic object is dynamic
and they require it before a type name in 2018.
So whoever is reading the code is immediately aware
that there is some polymorphism there,
which could be a performance hit,
or even just to know that it is an interface
which you can extend on.
And if you want to do this in a way
that's backwards compatible
without also breaking the previous code,
the only way you could do this is basically saying,
okay, I take this module from 2015,
this module from 2018, I compile them to some sort of intermediate representation, which
is common between them, and then they can communicate.
So basically what happens is that the compiler has support for all the epochs, and in the
rest they're called additions, and they compile to the same AST, and then these ASTs can obviously
communicate together because they are the same intermediate representation.
I think it's a very elegant
way of fixing quirks
in the language, and in general
trying to make it safer
by default without completely changing
the way the language works, as the example
of the dyn keyword
shows. And my
idea was basically, let's try to bring this to
C++ and see how we could do it, see
what we could fix, and
if it's worth it, and what we have
to say to the committee to convince them
that the idea is worthwhile. So
I basically wrote this blog post that has
some diagrams that explain in a
visual way what these epochs or
additions would be for C++.
And the idea is that we should
leverage the new module system,
which is going to be shipped soon,
as it's basically a self-contained unit of code,
and it will compile to some sort of binary representation
that is, you know, it will be independent
from the syntax of the language.
So there is pretty much nothing preventing us from saying,
okay, this module is using the language version number two, this module is using language version number three, and we can change the meaning of the keywords and the syntax between versions while still retaining compatibility between the modules as the intermediate representation, which is the binary format or the ST or whatever, is still the same. Ideas of things we could change range from completely insane,
like making the language const by default
and adding a mutable keyword to have mutable variables.
Oh, that's the sane recommendation,
not the insane one.
I wish, I mean, I would love this,
but the risk there is that
when somebody is trying to read C++ code,
now they have to have a switch in their
brain and they say, you know, this is C++ with this epoch and this is C++ with this other epoch.
And trying to read code which looks the same but is very different can be a problem.
The other thing is we could do things that make the language a little bit safer by default.
They remove pitfalls that especially catch newcomers
and don't give any problem to the experts
and make the code easier to read.
As an example, one of my favorite things
I would like to see from this is
just prevent uninitialized variables
without an explicit syntax.
Like if you write int i semicolon,
that should be a compile time error
because it's a source of bugs.
Often people,
especially newcomers, leave variables initialized by accident, and the problem seems to work,
and then they have to describe what on the fact behavior is and so on. But if we have like an explicit syntax, like int i equals uninitialized, or int i equals void, which I think is what d does,
then the programmer has to consciously say, okay, in this
code, I want this variable to be uninitialized. So it's just a few extra keystrokes, but it forces
you to think about whether you want to initialize or not. And it makes it obvious to the reader that
they need to be careful while reviewing the code and make sure that the variable is always going
to be initialized. So this is an example of something we could do. Another example that I think is very worthwhile is preventing implicit
conversions. Like nowadays, you can simply say int i equals 3.5, right? It's going to compile,
it's going to give you a warning. But you know, it's usually a bug, like you probably don't want
a conversion, I would like to see the language move into a direction where you require a cast there,
like a cast is mandatory.
So you need to be sure that a conversion is taking place
and whoever is the code also is fully aware
that there is a potentially narrowing conversion there.
So all of these small tweaks,
I think they don't change the way the language works.
I think they don't spawn new dialects.
I think they don't really force people to learn different epochs. They are just minor fixes that can actually make
the code a little safer, both for experts and newcomers. And this would bring new people to
C++ because they see that we are making the language more friendly to beginners and also
prevent bugs that everybody makes. Like, I make these bugs. I make these mistakes.
And, you know, sometimes I just leave this verb initialized by accident once in a million, right?
But I like that not to happen.
I like the compiler to tell me, what are you doing?
Do you actually want this to be uninitialized or did you make a mistake?
So I think these things are entirely reasonable.
What do you think?
I kind of like the idea.
I think it's doable.
I think to all the people that say,
oh, why don't you just break backward compatibility?
I say, can I introduce you to my friend Python 3?
Which I still run into people that are like,
oh, yeah, no, we just can't update our code
from Python 2 to Python 3.
We're still using Python 2.
I'm like, you know, that was like 18 years ago, right?
Or whatever.
I mean, it was a long time ago.
It was before Vittorio was born, I'm pretty sure.
Python 3 came out.
And so we clearly can't just break the language,
but if we just had some way, what is it like?
I mean, there's some precedent for similar things besides rust like uh option explicit and like visual basic versions
right i think that's right where at the top of the file you would have to say like uh you must
declare variables because in some languages you know you don't have to declare a variable before
you use it that kind of thing um i think it's kind of a similar kind of idea.
I've actually done some research.
Like, I'm surprised there are many languages that do something like this.
There's Ustrict in JavaScript.
I think Perl or something similar.
And even C Sharp, like in the latest version,
they basically finally realized that having nullable variables by default
is probably not a smart idea.
So now you can opt in at the beginning of your file and you say,
no, I want to be explicit about nullables.
And you have to put the question mark after the type.
So it's something that languages seem to be moving towards.
And it's a per file basis.
Yeah, Rust is fairly new.
But if you think about it, like it seems very sound
and it has been working for them for four or five years
so it's fair to say like there is no multi-decade experience but it also fairs to say that if you
think about it from technical point of view it kind of makes sense and you can see that there
is a trend in languages to move towards this direction and i think we really need it like i
don't want a python 2.3 schism or another possibility would be
completely changing the language
with the same technique
like having an EPUB
that completely changes the language
and makes it super nice.
But still, you like making a new language
and you're forcing people
to be able to switch back and forth
which is not something impossible
but I
rather keep C++ as a linear chronology of small changes that continuously make the language
more refined and safer to use.
And I think, honestly, if I can find a way to get the message across the committee, I
am confident they would see the value in this and hopefully understand that
there is no risk of creating dialects.
There is a risk.
Like when we have the feature,
obviously you can propose crazy stuff,
but every single proposal would have to be treated
like a proposal to the main language, right?
We don't want to break language compatibility.
We don't want to surprise users.
So what we would do in an EPUB would be something small,
positive change, maybe a little bit more verbose code,
but safer defaults.
That's what I want.
The counter argument would be maybe this is not impactful enough
to warrant a new feature like EPUBs.
But I strongly believe that everybody makes mistakes
and also if we want to survive it has to be friendlier and safer for newcomers like you
can't expect newcomers to be able to know all the warning switches and all the quirks and stuff like
that like the code has to be more explicit and unsafe code should be allowed but it should be you know marked with a big red sign
that says i'm i actually know what i'm doing right i want this to be unsafe all right so go ahead
jason that's gonna say if you could wave a magic wand right now what would be the very first thing
that you would do in the epoch like pick one thing thing. What's the first thing? It's a tough question. Nope. And you only get one answer just for the record.
Fine, fine. Um, I, I intuitively, I would immediately say implicit conversions. I think
are a source of bugs and incomprehension when reading the code more than initialized variables.
Um, especially when it's very subtle, like inside some if statement, you get a contextual conversion that is usually beneficial,
but in a particular use case scenario, it actually makes your code do the wrong thing.
And it's really hard to pinpoint what the problem is,
because if you enable W conversion, you're going to get it in a million places.
So I would like to see implicit conversions go, or at least most of them.
And just basically have explicit by default everywhere
and force people to have casts.
And this is especially important
when you have code that's doing a lot of arithmetic or numerics
because it's really easy to introduce subtle bugs
just by having integer promotions happen
or having narrowing conversions happen
while you're doing some maths inside your expressions,
it's hard to spot and it's a source of mistakes.
Just imagine a ternary operator.
Like if I swear, if I tell anybody,
please tell me what the result of this ternary operator is,
where there's a bunch of signed and unsigned types
and stuff like that.
It's really hard, right?
That shouldn't be like that.
It should be explicit in the code what the thing is going to be,
and it should force you to decide what you should evaluate to.
Like, you don't want to go through the wording in your head
and try and understand what a type would be.
And maybe it doesn't matter for most of the code,
but when you're having some sort of value that's important
and you don't
want it to be narrow you don't want to lose information we don't want the sign to be wrong
and stuff like that and it's buried deep inside your program you're gonna be happy that you have
to write those extra casts manually even if they're longer because they're gonna save you hours of pain
and suffering i wanted to interrupt the discussion for just a moment to talk about the sponsor of this episode of CppCast, the PVS Studio team.
The team promotes the practice of writing high-quality code, as well as the methodology of static code analysis.
In their blog, you'll find many articles on programming, code security, checks of open-source projects, and much more. For example, they've recently posted an article which demonstrates not in theory, but in practice, that many pull requests on GitHub related to bug fixing could have been avoided if code authors regularly use static code analysis.
Speaking of which, another recent article shows how to set up regular runs of the PVS Studio static code analyzer on Travis CI.
Links to these publications are in the show notes for this episode. Try PVS Studio. The tool will help you find bugs and potential vulnerabilities in the code of programs written in C, C++, C Sharp, and Java.
So I wanted to back up a little bit and talk a little bit more about how this would work in practice. 2023, C++ 23 is out, and we have this feature, and you have an application, and you want to consume
both like a C++ 20 epoch library and a 23 epoch library that should just work seamlessly?
Yes. So my understanding, I'm not an expert on modules. So I want to say this as a disclaimer.
With my understanding that I have, I think this is entirely possible on technical side but if
someone comes along and says wait you are missing this detail about modules that would make this
impossible then sure now assuming that my understanding is correct which is basically
you know every compiler given a module will produce some sort of binary object which is
independent from the c++ syntax so it's basically binary AST representation or metadata
which contains all the information that's required to consume the module, then in 23,
you might imagine we have this new 23 epoch, and some modules will have it, some modules
won't.
However, when you compile them, they will all produce the same kind of AST language
or binary language that contains information required.
And then you can simply link the modules together
or consume a module's interface from the other
because all the information is the same.
So this is my understanding
and this is how I predict it would work.
Does that answer your question?
Yeah, I think so.
I feel like it should absolutely be...
I mean, my gut also says that it should be workable,
assuming that none of these epochs change the layout of an object
or somehow affect calling conventions, basically.
So I think that there is a risk there.
I definitely don't want to touch anything related to library or ABI, at least in the first epochs.
What I would like to see is fixed language syntax.
That's basically it.
Let's start with that.
See how it goes.
It's very low risk.
And if we see that this is the way forward, then maybe we can start thinking about things that are a little bit more risky.
Like, for example, create an alias for std x that in the module automatically becomes stdy.
So something that kind of converts a dangerous type to a non-dangerous one.
But then you have the ABI implications and you might introduce extra conversions another
thing that i think is reasonable is as an example take std optional i think that the default should
be when you use the star operator it shouldn't be ub it should throw if the value is not there
and then you should have something like unsafe get so you can be explicit and you can say okay
i'm sure this thing has something inside it and I want to grab it outside.
So maybe what we could do is some sort of notation
where you say, okay, this method is enabled
from epoch A to epoch B
and is disabled from then onwards
and this method is only available from epoch B onwards.
So kind of like fixing the interface of standard types
without changing the layout,
which wouldn't affect ABI
as far as my understanding goes, but it would make the interface safer and easier to use.
It's an interesting one to mention because optional is by far not unique when it comes to
that kind of UB, right? Like, would you also then make the checked interfaces the defaults around vector
and shared pointer and unique pointer and that kind of thing as well?
I don't think it's a completely unreasonable train of thought.
As I mentioned before, this is something that would come later
and has to be considered very deeply because it has deep implications for the language.
But I think there was a survey recently,
and bugs caused by unchecked vector access
were the most common ones.
I think it was actually a talk
by the most common bugs at Facebook or something like that.
And the truth is that if you provide an interface
which is unsafe by default,
and it's the most convenient to use,
then you're going to have a bad time, right right those two things shouldn't match it should be either
convenient and safe or slightly less convenient and unsafe so i believe that if c++ wants to
compete with the newer languages that have a little bit of more sound underlying principles
regarding interface design like rust then maybe this direction might be
worthwhile. And again, I don't want to come in in the committee and say, hey, we have these new
features called Epochs, we need it, and we need it because we want to fix the language. I want to
take it like a very gradual approach, sell the idea of Epochs first, sell the very small but
very beneficial changes, like as i mentioned initialized variables which
i hope would be you know not very controversial i hope everybody can agree that initialized variables
are often a source of bugs and it should be more explicit and then judging from how that goes
we can start thinking about you know changing the way we do defaults, making them safer, making them more friendly
to both newcomers and experts. And again, that needs to be done with a lot of thought and care.
It's not something we can just jump into and say, okay, let's just fix the language completely,
because that's not going to happen. And that would just kill the proposal.
It wouldn't. And yeah, it would get hung up in the committee, I think, for a decade trying to
figure out what the first epoch should be if you tried to make it more aggressive.
So since we're talking about the committee, you wrote this blog post a couple weeks ago, and you are a committee member.
I believe you went to Cologne, right?
I do go to meetings.
My affiliation is with Bloomberg, so I go on behalf of the company. Right.
So have you gotten much feedback?
Do you plan on putting together an actual paper for a future meeting?
So I have not discussed this in Cologne.
What I did was back in Jacksonville, which was, I think, last year, I did flow this idea around in Evolution.
But it was, you know, just just as a comment reply to another comment
and the vibe i got for the room was very very uh negative in the sense that everybody was
immediately saying hey you're gonna create a lot of dialects it's gonna completely change the
language people are not gonna know what kind of things they are writing and what i tried to do
with this blog post was answer those, I would say...
Concerns, yes, those concerns.
Because I think that if you do this in an incorrect way,
you can definitely go into that direction, and we don't want to do that.
But if you take this step by step, you do it properly,
there is no risk of getting dialects and making the language impossible to understand.
So there are fair concerns.
I think there's a little bit of extreme reactions
because you need to understand the tough principle
behind those very small gradual changes
before you can accept the idea of changing the syntax.
But hopefully I will write a paper for the next meeting
and I believe it will be something very simple,
just showing the idea and just showing a few possible minor changes.
And I think I will target Yugi.
So it's EWGI, which is the incubator.
And yeah, the incubator is usually more lenient
and they give you a lot more feedback
how now you can present this in a more convincing way
to evolution so i think having the first step getting the initial feedback and you know even
just like friendly advice something like hey if you change this paragraph to this and if you remove
this bullet point maybe you will get less concern evolution because there are people that have been
bitten by this in the past or stuff like that. So something like this, I think, would be a great first step.
Also, Jason, we can probably fix initializer list with this.
That's right.
You were in that room when I gave that talk, weren't you?
Yes, I was there.
Yeah.
Yes.
Well, more implicit moves, but not with initializer list.
Anyhow.
So you have gotten some good feedback
and you're definitely going to pursue writing a paper for this.
Good feedback from the blog.
I got overwhelming positive response.
Like everybody, I don't want to say everybody,
but like the majority of people were like,
we definitely need this or something like this.
Like I cannot envision C++ continuing in the future without a way of
changing these very very bad defaults and very very bad syntaxes that lead people to make mistakes
so the sentiment is that people want something like this which is really good to hear
i've also had some criticism uh both constructive and non-constructive let's put it this way
but a constructive one uh
was also very valuable and you know the fact that rust is not very um you know it's not very baked
is a very important one like we need to be careful and see if this thing can scale in the future
and also the other feedback was you know this can be abused so it has to be very clear that the goal of this is not revolutionizing the way you write C++, but incrementally and linearly changing this.
I believe there are some languages, even REST does this in a way.
At the beginning of your file, you can have enable and disable features independently.
So you can say maybe this file uses this particular syntax
but not this other one i don't really want to go down that route because then you get into the
problem that to understand what code you're reading you have to keep in mind all those
switches in your head so what i want to do is basically have some linear gradual polishing
of the language that's it like i don't want those kind of nubs. So all of this criticism was really, really useful.
I might actually write a follow-up post
because I have collected a lot of interesting things
that are worth mentioning.
So I might do that.
Otherwise, I will capture them in the paper.
So it's been a really great response, I think.
And I'm happy to see that the community
wants something like this,
that I'm happy to see that the community wants something like this, that I'm not
crazy. And, you know, I have hope for this. Let's see. I'm curious, because I think Bjarne has said
that making this a pointer is a design flaw in the language. But he couldn't have made this a
reference because he created this before references were added to the language. So I'm kind of curious what his specific take would be like.
Tell you what, we can make an epoch, and this is now a reference.
I can see how he responds to that.
I believe that Bjarne is very, very concerned
about not splitting the community and not creating dialects right so i
think that this side of him would overpower the side where he realizes that the initial decision
for this was a mistake i i wouldn't want to see like i would agree with him i wouldn't want to
see two different source files and one says this arrow and then the other one says this dot okay because then it becomes really hard to teach like you're gonna have to teach people
you know before it used to be a pointer now it's a reference but it's the same syntax
and then you know just i don't really like that right if we if we did something a little bit
different like for example ban this and add a self keyword you know it might be better in a way because at least you're
not changing the meaning of an existing keyword and creating this sort of hey mental switch is
more like a new thing however i don't think this is like a very major problem like i don't believe
that this pointer is a source of bugs or inconvenience you know's just weird. It used to be.
Why did it used to be?
Oh, there was actually,
it's been long enough ago now,
that GCC made it the default at some point in my recent memory
to optimize around checks for this being null
because there used to be a bunch of old code
that relied on being able to check to see if this being null because there used to be a bunch of old code that relied on being able
to check to see if this was null if they were actively operating on an active object and when
gcc made this the default like clang and everyone else had already been doing this when gcc made it
i think it was made at the default but and it was it was a while ago now it like caused this
uproar because they're like you broke broke my code! I'm like, no, your code was already broken.
So yeah, it was a thing.
It was a thing.
Like, old school C++ stuff had some really bad habits in it.
I see.
I think I remember that.
Actually, I think it was a few years ago.
I do remember there was a huge uproar about this.
I wouldn't say that though this is like... I would say this is caused by the fact that this is a pointer,
but it is still completely broken code in the sense...
Oh, yeah.
You can't check if your selfies are null.
It's not the same.
This is like completely misunderstanding of how C++ works
compared to leaving a variable initialized by mistake.
That's my – it's not a very strong argument, but I think there's a fundamental difference in these two bugs.
The first one is like you have no idea what you're doing, right?
The second one is more like, yeah, you might have an idea what you're doing, but sometimes people make mistakes.
So I think that for the first ones,
we should probably think carefully about fixing those because it's not a common scenario.
Right, right.
I agree.
And I think checking if this is null is something today
all compilers will warn on, even with warnings disabled.
Okay.
Because it's like uh no
uh so you're gonna be at cvcon this year uh giving a talk do you want to tell us a little
bit about uh what your talk will be oh yeah yeah so the other thing i've been involved into uh
in regards to the standardization was this proposal called function ref and basically imagine something like string
view for functions that's very rough approximation but the idea is you know i give you this function
ref with a given signature and then this thing can refer to any callable which matches the signature
and the benefit to our function std function is that it's super fast. If everything gets in line, it's exactly the same as a template parameter.
So it's quite nice.
It doesn't require templates, so you can use it in polymorphic interfaces
without getting the cost of std function.
And the other thing I really like is that it makes it really clear from the signature
that whoever is consuming this function is not going to store it.
You know, it's just reading it, calling it, and then
giving it back. So it makes it obvious it's
a borrowed function. Sometimes
with a CD function, you don't know when you get
a constant CD function ref if that
thing is going to be retained or not.
Well, this one makes it obvious.
Anyway, I have a talk on this
at CVEcon, which is going to be like an updated
version of a talk I gave
beforehand at a few other conferences.
And I got a really good
feedback at all the previous iterations
of the talk, and I'm going to incorporate it in CpvCon.
I'm going to try to make the ultimate version of the talk.
You're running out of time.
Oh, yeah. I'll be good.
So, yeah.
It's two weeks. If you're interested
in the history of our proposal
that started from a tweet from Eric Nibler, which said, this is a proposal to write itself.
And then he went through like six iterations and it's still not in C++.
Then you should come to the talk.
I think it's really educational to see how many very tricky edge cases and very tricky design decisions have had to be made.
Right.
And still not everybody is happy with this.
But it was supposed
to go into 20.
It just didn't go in
because of a lack of time.
So I'm very confident
this will be in 23.
The other thing
I'm going to be doing
at CPCon
is a pre-conference class
about CPCon 11 and 14.
And this is my first time
giving a class
so I'm really excited.
I've been doing this
inside a company,
you know,
inside my company
but never as a public
trainer. So this is a new
thing for me and i hope it will go well i really enjoy teaching and what i'm basically going to do
is give people that are very experienced with sales plus three a very quick overview and up
to speed course to sales plus 11 and 14 all the language features and the most important library
features and there is going to be a very big focus
on interactivity. So what I'm going to do is
basically have the attendees
convert a C++3
implementation of std vector to
C++14 and see how you can use
the new features to make the internals better,
the API better, and even
some non-orthodox things like
adding map, reduce,
and transform to the vector
to play around with lambda expression and stuff like that
so I've
done a version of this course internally at Bloomberg
for like 11 or
12 times and every time the feedback
has been stellar because
I think I hit the right spot between
you know the speed which I
teach stuff, the interactivity
and the fact that people already know C++, so I don't have to
explain every little detail.
And I'm really excited to
do this at CppCon. I think that
even though it's 2019,
there are still people that have
been working in C++3, either for reasons
regarding legacy architectures,
or because they never had a
need to move to 2014.
And my intention is like to
capture all the different use cases show people how these features can make your code better with
like real examples and make them play around with it because i think if it's just a lecture if
there's no interactivity it won't be as stuck in their mind as it would be otherwise so i hope that
will be very well received.
And I think there's still spots left.
So if you're interested in that,
or if you know anybody that hasn't had enough exposure to the new standards,
that would be a good thing to suggest.
I got to ask a question about function ref.
If you don't mind backtracking to that just a second.
Does it ever dynamically allocate?
No, absolutely not. It's always the size of two
pointers always the size of two pointers so i need to come to your talk to understand how you can do
type erasure and never have dynamic allocations yep i will welcome you to my talk uh but like
the gist of it is this thing never owns the function.
It only refers to an existing one.
So the caveat is that you have to be careful with the lifetime
of the thing you're passing to function ref,
as it will not extend it.
But the only type of ratio is the type of ratio of the colon, colon operator call.
So nothing else.
I'm going to show you how it's done.
It's actually quite simple and it's
easy to implement, but there are some, as I mentioned, edge cases and decisions you have
to make in a design process as unfortunately there is no design or memory layout of this
thing that will please everybody. Yeah. Okay. That sounds tricky to get right. Yeah, it is.
All right, cool. Okay. Well, there anything else uh you wanted to go over
before we let you go today vittorio um talked about a lot yeah i talked about a lot i i would
not really anything in particular i just want to say that like the epochs effort and even things
like function rev uh they're really driven by feedback and by what people want to need. So I really appreciated the reception to what I've done so far.
And if anybody's listening to this cast and they have ideas or feedback,
whether positive or negative on any of these initiatives,
I just think it's important to get it out early and, you know,
without being scared of saying it, even if it might destroy the proposals.
You know, I appreciate that and I think it's important.
So just, you know, an encouragement for people and listeners to participate,
not just in my initiatives and my efforts,
but in general, try to be active into things they care about.
And people writing proposals, people going to the meetings,
they're always open to feedback from anybody.
I can just find their emails or just find their LinkedIn, whatever.
They appreciate that, so please do that.
It's good.
Yeah, it does sound very important that if someone says,
no, it's absolutely impossible for epochs to work with modules because of X,
you want to know that information like yesterday.
Yes, exactly.
Okay.
You know, there's one thing I think I remember from the blog post,
I don't think we discussed at all,
and you do want part of this to be providing some way to migrate from, like, one epoch to the next, right?
Oh, yeah.
A library should opt in.
Like, I want to be a 23 epoch.
That's something that you want to be able to, like, script them to help do as part of this?
Yeah.
So this is actually another thing that Rust tries to do.
Like, what they do is their compiler has a
fixed flag or something like that I can't remember the exact name of the flag but it can do most of
the transformations from one input to the other automatically like the things that I mentioned
like a dyn keyword is basically just you know find all the places this is a polymorphic reference
and just stick the the keyboard there so all of these changes are quite possible.
And actually, if you've used the amazing CPP Insights tool by Andreas Vertig, I think the name is,
that shows you all the implicit conversions.
So we already have the technology
to change the implicit conversion to explicit ones
by adding the cast in the right places.
So all of these things are possible,
and I think it would be a lot easier
for people to migrate from one
epoch to the other if most
if not all of the
changes would be automated. And the
scope of the changes I have in mind
they should definitely be possible
to be automated. And maybe that's also a good
design guideline. Like try to do
things that could be automated. And if
you go outside of that then maybe
think again whether that's a positive change
or not between epochs.
Okay, makes sense.
Okay, well, it's been great
having you on the show today, Vittorio.
Thank you so much for having me.
Likewise, it's been good,
I guess, like many years ago.
Yeah, thanks for coming on.
Cheers.
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