CppCast - Safety, Security and Modern C++, with Bjarne Stroustrup
Episode Date: July 21, 2023Bjarne Stroustrup joins Phil and Timur. Bjarne talks to us about safety in C++ through profiles, as well as modules and concepts - and looks ahead to what else is coming next. News C++ Now 20...23 videos ACCU 2023 videos JetBrains Developer Ecosystem Survey 2023 Upcoming Boost 1.83 release Links P2739R0 - 'A call to action: Think seriously about “safety"; then do something sensible about it' P2687R0 - 'Design Alternatives for Type-and-Resource Safe C++' 'Contemporary C++ in Action' (video) - Daniela Engert
Transcript
Discussion (0)
Episode 365 of CppCast with guest Bjarne Stroustrup, recorded 11th of July 2023.
This episode is sponsored by JetBrains, smart IDEs to help with C++.
And Sona, the home of clean code. In this episode, we talk about the upcoming Boost release and other news from the C++ world.
Then we are joined by Bjarne Stuster.
Bjarne talks to us about modules, concepts, and safety
and security in C++.
Welcome to episode 365 of CppCast, the first podcast for C++ developers by C++ developers.
I'm your host, Timo Dummler, joined by my co-host, Phil Nash.
Phil, how are you doing today?
I'm all right, Timo. How are you doing?
Oh, yeah, not too bad.
I had a last week off, so we went to the summer cottage.
It's called the Möki.
That's like the thing that all the Finnish people do.
It's kind of in a countryside, no internet,
no by the lake. That was very pleasant. This week I'm back. So yeah, doing pretty well,
feeling reasonably relaxed. How about you, Phil? I'm jealous. I was working last week,
but I was taking it a little bit easier. I think I've fully recovered now from C++ on C, so back on track, ready to face the world, I think.
All right.
So you're actually going on vacation as well soon, right, Phil?
Yeah, in about three weeks.
So in fact, I'm going to be away for three weeks, which means we're going to have to cover two of the episodes.
So we're going to have a couple of guest hosts, and we're not going to tell you who they are
until the time, just to leave a little bit of mystery around it yeah but uh yeah i'm very excited uh you're gonna have some really cool
guests co-hosts so you can look forward to that all right so um at the top of every episode i
like to read a piece of feedback this week we actually don't have any new feedback because
we released the last episode only four days before we were recording this one and that's
because next week i'll be in toronto and canada for the cbus cpp four days before we were recording this one. And that's because next week I'll be in Toronto and Canada for the CBP North conference.
And we kind of have to finish all the editing before I go there.
So we only had a few days before recording, kind of publishing the last one and recording
this one.
So we didn't get any feedback in that short amount of time yet.
But yeah, I hope that we're going to get some.
Yes. Good opportunity just to remind people that it's nice to get some feedback, especially to read out on the show. So if you've got anything
to say to us, do let us know on any of the channels that we mentioned. So yes, we'd like
to hear your thoughts about the show. And you can always reach out to us on Twitter or Mastodon or
email us at feedback at cppcast.com. Joining us today is Bjarne Stroustrup.
Bjarne Stroustrup is the designer and original implementer of C++, as well as the author
of the C++ Programming Language, a Tour of C++, and many popular and academic publications.
He is a professor of computer science in Columbia University in New York City, a member of the
U.S. National Academy of Engineering, and an IEEE ACM and CHM
fellow. His research interests include distributed systems, design, programming techniques, software
development tools, and programming languages. To make C++ a stable and up-to-date base for real
world software development, he has been a leading figure with the ISO C++ standards effort for more
than 30 years. He holds a master's in mathematics from Aarhus University,
where he's an honorary professor in the computer science department
and a PhD in computer science from Cambridge University,
where he is an honorary fellow of Churchill College.
Piano, welcome to the show.
Well, thank you very much.
It's good to be here again.
So it's usually at this point in the show
that I'll pick on something in the bio and ask a
question but i think you know to be honest i don't really have anything to say so i think we should
just get straight into the uh into the material well one thing that i'll say is that um last time
you've been on the show bianna is actually over six years ago it was i think in may 2017
so overdue a long time thank you so much for joining us again.
We really appreciate that. I mean, C++ is long lived and still growing.
Yes, I don't think we're going to talk about that. Yes, you will. So, Bjarne, we'll get more into
your work in just a few minutes, but we have a couple of news articles to talk about first. So,
if you'll feature a comment on any of those, if you like. So, the first one I have is there's a
bunch of new C++ conference videos. So, if you like watching conference the first one I have is there's a bunch of new C++ conference videos.
So if you like watching conference talks on YouTube for free, there's more stuff now for you.
So C++ Now, which is the conference that happened in May just a couple of months ago,
just released the first five videos on their YouTube channel for free.
And the remaining videos from that conference will be released over the next
couple of months.
And then videos from ACCU 2023,
which is a conference in the UK that happened in April,
also started appearing on YouTube.
So they're kind of coming out one after the other.
So I imagine that over the course of the next few weeks,
all that content is going to be available as well.
So there's lots of material.
Have fun watching it. i think there's some
really really great talks in there i've been to both conferences and yeah there's some really
good content uh there so i'm very happy that you know everybody gets to access it for free
obviously we'll put the links to those in the show notes all right the second news item i have
is um jetpains is running a developer ecosystem survey again this year just like every year
so it's the seventh time they're doing this.
And it's a survey to explore the current state
of the software development industry.
It takes about 25 minutes to complete,
and everybody who completes the survey
with meaningful answers will have the chance
to win a prize of their choice,
which is either a MacBook Pro 16-inch
or an NVIDIA GeForce RTX 1490 graphics card
or an iPhone 14
Pro or a Samsung Galaxy or a
$300 Amazon certificate
or a JetBrain's all-products pack.
So, answer
the survey, choose which
price you prefer, and then
good luck. And the results
of the survey, as always, will be published
publicly, so they will be available for free.
And it's one of, I think,
three surveys that are
going on regularly. There's the JetBrains one, there's the one
by Meeting C++, and there's the one that
the C++ Foundation
runs. And yeah,
I think all three of those are kind of, it's really
good and important to have a
snapshot of where the community is.
So yeah, I encourage you to support
to put that effort and answer the survey.
It's kind of fun.
Yeah, and as I said before, those of us
that do work in tooling,
we do monitor these surveys
to give us an idea of
the pulse of the community and
what things are needed, what things
are being used. It's very useful.
Alright, and the last news item
I have for today is about the upcoming
Boost release.
So Boost is going to release
their version 1.83
at some point,
I think in the near future.
There is no release date
as far as I can see,
but that's going to be
the last release
that is going to support
C++ 03.
And the reason I'm talking
about this now,
even though there is no
big announcement
that it's out
or anything like that,
is because I noticed that there was a blog post about a particular new feature in that upcoming Boost release,
which is Boost Unaudited, which is now providing a new container, Boost Concurrent Flatmap.
And there is a pretty detailed blog post about how it all works.
So it's an associative container. It's kind of based on Boost Unordered Flatmap,
but it's thread-safe
and it's suitable for high-load parallel scenarios.
And
yes, it is
based on Boost Unordered Flatmap,
but it has some very interesting innovations,
in particular how they do
concurrency. There's multiple levels to it.
There's, on the container level,
there's a read-write mutex for which you kind of lock for write access only if you have like whole container operations
like rehashing or swap or assignment and then like one level lower you have like each each kind
of group inside the container has like a dedicated read write spin lock to control access to its
slots and there's like lots of machinery, how it's all designed.
And it's like a detailed blog post describing all this.
So I thought that was really impressive.
The other thing that I thought was really impressive
is that that blog post has benchmarks
where they compare that concurrent flat map
to two other implementations, one by TBB and one by GTL.
And it looks to me that Boost's concurrent flat map
seems to outperform both of them,
which is also very interesting.
Yeah, if you're
into concurrent programming, it's a really
cool blog post. They kind of describe the strategy,
how they do the synchronization in an
effective way.
That's pretty cool.
Yeah, I didn't look at the specific
library you mentioned here, but
we don't talk about Boost that much these days,
or both on the show and maybe in the community as well,
but it's still going strong.
Obviously, its role has changed a bit.
It used to be, well, it still is to some extent,
a breeding ground for libraries that may make it into the standard,
although not as much as it was back in the early days
when a lot of the libraries made it into C++11.
And these days, I think it's sort of,
for those that didn't make it onto C++11,
it became a bit of a polyfill library for some of those libraries.
So it's interesting that support for C++03 is finally going away.
I was actually surprised that it's still there.
So that's a bit of a milestone.
Yeah, they have a lot of
libraries in there which are
things that we have since C++11
or 14 or 17 like
Boost Any or Boost Variant
and there's a whole bunch of them
that we now have in the standard. So they're actually
not only dropping support for C++03
but they're also dropping support for all of those
libraries. Because
you kind of don't need them anymore.
They were useful as backports of all of these features to C++ 03,
but now that they don't support that anymore,
they're basically saying, well, just use the standard version.
Yeah.
And of course, the older versions will still be around
for those that are stuck on C++ 03.
All right.
So that's all the news items I have for today.
So we can move on to our main guest and our main topic.
Bjarne, welcome again to the show.
Yeah, hi.
How are you doing today?
Doing all right.
I'm out of New York for the summer.
I don't like New York summer weather, so I'm sitting back in my hometown of Aarhus in Denmark,
where it's peace and quiet and you can get some work done.
Nice.
Yeah, that sounds great.
Yeah, we were actually saying before we hit the record button
that Phil is in the UK, I'm in Finland, and you're in Denmark,
so you're kind of right in between us geographically.
Yeah.
So what you want to talk about today with you is a bunch of things,
but I would like to start with this topic of safety and security in C++,
which a lot of people have talked about this last year and this year.
There were a bunch of conference talks given on the topic,
lots of papers being written.
So it is a really hot topic in the community right now.
But one thing that I found interesting is you published a paper
back in december 2022
p2739 r0 a call to action think seriously about safety then do something sensible about it
and that paper did receive some criticism in the community um but i think some aspects of
the paper were kind of misunderstood maybe and um i actually think there's like some really great
ideas in there so i kind of just thought it would be actually think there's like some really great ideas in there.
So I kind of just thought
it would be cool to invite you to the show
and talk a little bit
and a little bit more detail
about your work there
and what the idea is
and how that can lead us
to more safe and secure C++.
Yeah.
Software is everywhere.
And that means it's deep in our critical infrastructure. And obviously, the security guys are very interested in that. Obviously, people who are into reliability is very interested in various forms of safety. And I've been working on this for a long time. I was the major person involved in
generating the JSF++ guidelines for writing flight software for fighter planes, where safety is a rather important thing. And that was in the early 2000s, and I've been working on and off for this for ages.
And, of course, part of the original inspiration of C++ was to get something that was easier to write
and harder to make mistakes at than C.
So we got classes and later smart pointers and containers
and that kind of stuff.
So I've been working on a gradual progression towards a more
type-safe language and more productive language at the same time
by emphasizing abstraction. And my call to action was that I thought that the C++ Standards Committee
was not focused well enough on that aspect of C++.
A lot of people were trying to improve their own little corner of the language,
ignoring the big picture.
And so I wanted the big picture in place for which safety, for some definition of safety,
is important, but also the usual engineering balancing of concerns.
And so that was it. And I followed up together with Gabidos Reyes
with discussions of how you could get a safer C++
aiming at a very fireably safe C++
which led to the work on profiles
which says specify what you mean by safety
and then find ways of enforcing that kind of safety in the language.
The assumption here, the fundamental assumption is that safety is not one thing.
It's a variety of things.
My favorite, of course, is the usual type and resource safety.
Notice the resource.
It's not just type safe.
If you leak resources, your system stops.
That's not a good idea.
So we need both type safety and resource safety.
We don't leak.
And there's some design for that, and they've been prototyped in
the core guidelines, which you can go and use. It's not perfectly implemented, partly because
people haven't focused on it. And one of the reasons for my call to action was I wanted people
to focus on it. We need improvements in type safety.
We need improvements in containers.
We need improvements in particular in static analysis,
which is needed for getting verifiably safe code
without runtime overheads.
In particular, we have to eliminate dangling pointers. And you can go back in the
last five to eight years, you can find talks by me on this particular topic. So there's nothing
new. We didn't start yesterday because somebody was interested in safety. we've been there for a long time.
So you talk about type and resource safety,
and usually when we hear safety in C++ talked about,
particularly in the NSA and the Consumer Reports articles,
the focus has been on memory safety,
which I presume is a subset of resource safety.
It is.
So memory safety is a subset of type safety and resource safety.
Basically, you want to guarantee that every object is used only in accordance to the type it was defined with. So if you can have a range overflow, then I can manipulate your object out there through my interface, usually by accident.
So if you have a dangling pointer, you update something or read something that's just not there anymore.
Something else might be there and you can mess up things.
This has to be eliminated.
And it can be eliminated with a combination of making sure that you know where the pointers point to.
The most important thing is that if I get a pointer, I can return that back,
because if it was valid, I can return it back.
Also, I can return a pointer that points to something static or something allocated on the free store.
That kind of stuff can be enforced.
And then you have to enforce the invalidation rules that you can actually find in the standard in places. If I take a pointer to an element of a vector,
then do a pushback on the vector,
the vector might reallocate all the elements.
Now your pointer points to something wrong.
It's a dangling pointer.
This can be eliminated through static analysis
and basically it's called invalidation.
So the sum of these kinds of concerns can guarantee complete type safety.
And since resource, if you leak resources, you can do a denial of service attack,
you can have real controlling gadgets on some kind of vehicle just run out of resources and stop.
This is unacceptable.
And I see that as part of the enforcement of real type safety.
So type and resource safety is what I'm aiming for.
Memory safety is a subset of that.
It's necessary but not sufficient.
And I'd like to emphasize that this is not the only kind of safety we're interested in.
If you're doing a real-time system and something bad happens if you don't respond in a millisecond,
you have to have some guarantees that things happen in a shorter time than a millisecond.
And you can imagine profiles for other things, such as I'd like to see a teaching profile,
which basically is type and resource safe, but also stops you from using weird features of the language
that you don't want your students to get into, so they really need to.
That is my sort of the professor side of me is interested in that.
And the other thing is that you would like your arithmetic not to overflow in some contexts.
And that's another profile.
So in my paper, together with Gabby, we listed 10 profiles that are plausible.
And we would like the fundamental ones, like type and resource safety,
to be defined and directly supported by the standard.
Other profiles are more specific to a specific domain or industry or company.
So it's an open set.
Right.
And I'm not the only one thinking about profiles.
After talking about this for a while, somebody came and said,
have you seen that they have something called profiles in Ada?
And that's actually one of the languages that are most interested
in safety and reliability.
And, you know, what they call profile is essentially
what you call profiles.
So we have a case of sort of independently,
not only coming to the same concept, but naming it the same.
Now, I'm not totally ignorant of ADAP, but I didn't know that bit.
Yeah, that's interesting.
So the paper you're talking about is, I think, P2687,
Design Alternatives for Type and Resource Safe and resource safe c++ that's the one
that you co-authored with with gabi so it's a really interesting um paper so from what i
understand i think this is something that took me a while to understand is um these profiles that
you want to introduce like i don't know a performance profile or a secure profile or
a teaching profile they're not actually dialects of C++, right?
So the same code would mean the same thing in all of the profiles.
But the trick is that in some profiles, some code would be considered ill-formed,
not valid, because the static analysis tells you that you can't do that in this profile.
Is that more or less the idea?
I wouldn't use ill-formed.
They're just not part of that profile.
If you use something that's not part of the profile,
the checker will say, don't do that.
Try and dereference a null pointer.
No, don't.
So here's the $1 million question,
which I think people don't really know the answer to, I think.
But maybe you do. so i'm really curious if you take c++ with you know all the ub it has like one other definition of safety
that a lot of people like sean parent use and i also use in my cpp on c talk is uh say a safe
code is like when you don't have unbounded undefined behavior right so that's one way of
looking at it which i think overlaps a little bit with your definition.
Your definition is, I think, wider,
but also I think excludes things like race conditions and threat safety.
It seems like that's a bit of a different thing, but maybe not.
I don't want to put words in your mouth.
But the question is, can we actually eliminate all the UBE
by placing constraints on the language,
like making a subset of C++ by rejecting certain things with a static analysis tool,
and then still be left with a subset of the language that is expressive enough and useful enough to do real-world programming?
That's something that people don't agree what the answer to that question is.
I know. A lot of people base their agreement or disagreement on some specific view of C++.
Like a lot of the criticisms is of the mythical language C slash C++, which says C slash C++ is unsafe, you shouldn't use it. And the examples by and large is on C the way we wrote it 30 years ago,
not using the facilities.
Now, whether we can eliminate all of undefined behavior
without imposing runtime overheads is indeed an open question.
But the reason it's open is not the reason people usually think.
The point is that UB has been used in the optimization pipelines.
And so there's very often not one place you can say,
well, if you dereference a pointer, we can stop that by looking there
and only there.
It's sort of the various optimizing passes has different views.
So I think we can do it, but it's a practical issue of how we can do it in existing implementations.
And existing implementations have different constraints.
So when we go into the standards discussions, different compiler vendors will have different opinions,
and that's where the difficulty is.
Clearly, anything that provides a guarantee cannot have you be doing time travel elimination of tests.
So you can't have a Safe C++ without range checking.
And so the recommendation is don't ever dereference a raw pointer.
Use a span or a vector or something like that and make sure that it's
range checked. The original span in the core guidelines support library has checking and
that's the right thing to do. It disappeared when it got standardized, but we have to get the original back. Similarly, if we go for contracts, which
can help in some areas, we have to make sure that you cannot, with UP, eliminate a contract check.
But these are practical problems. This is engineering, not math. If it was just math,
we'd have the answer. We know that. I think I could prove it, that that's the math part.
Can I implement it?
Not by myself.
It involves quite a few people that works on compilers, and they have constraints.
One of the reasons I talked about a performance profile is that there are people who really want these very unsafe features
because they claim that is key to their performance. I'm not sure if they're right,
but I'm sure that the right software that's important, that depends on that assumption.
And we can't just throw that away and saying, okay, everything has to be safe. Everything has to conform to our
current definition of safe code. Well, there's billions of lines of code out there. There are
techniques and tricks that people swear by for delivering important products. And you know,
if we put a constraint in place, we should also have a place where the constraint is not enforced.
If you are writing a piece of safety-critical software, obviously you wouldn't use that profile.
You have to guarantee that that profile is not there.
You use the type and resource-safe profile for starters, possibly the arithmetic profile that takes care of overflows and that kind of stuff.
But there has to be an escape clause for people who are writing an isolated system.
If you're not connected to the web or if you're connected to the web
through a certified safe module, you can start doing things
that you wouldn't do sort of in public.
And also, this has also to do with the gradual introduction of this stuff.
These billion lines of code, I think I've never seen a piece of code that couldn't be
improved.
But it is very hard to take a whole system and fix it at once.
You have to take this library now, that library now,
that piece of code now.
Some has to be rewritten.
Others have to be carefully used,
like you can use an unsafe library through a safe interface,
for instance, so that you never feed it bad pointers or bad data.
Put a checking interface in the place and you can use the old code,
things like that.
Yeah, that's the paradox, isn't it?
A safe code has to be built on top of unsafe code.
Yes.
At the end of the day.
After all, there's hardware down at the bottom,
and that's not reliable either.
I mean, there's lots of work being done on making sure that the bad parts of a batch of chips is not used.
The chips are still there, but the compiler, the really low-level stuff in the compilers from Intel and AMD and such,
simply dodges the bad parts.
At that level, you don't have the safety that the mathematicians dream about.
You write a spaceship software and you get hit by a cosmic ray.
You just had this bit deciding that it's always wanted to be a one.
It's never going to be anything else.
Whatever you say, you can't convince it to be zero again.
And it's halfway to Mars.
You can't send a repairman.
So
the fact that
there are unsafe, unreliable
things is a fact. As you said,
we build reliable systems
out of unreliable parts.
It's one of the beauties of the system.
It's also a thing that gives bloat
if you don't do it right
because then you put layers upon layers
and you have to pay for those layers
even if nothing ever happens
or if something happens every what's blue moon.
You have to do better than that.
One point I wanted to pick up on because uh
i work for sonar so we do static analysis tools so i've talked a lot about static analysis
when you're talking about using static analysis here you talk about using existing tools
like like sonar lint or would we need to build something new for this i think you need to build
something new um i have not used your stuff directly.
I've read about it.
So if I'm making a mistake, it's an honest mistake, and you can correct me. But we cannot prove arbitrary C++ code correct statically.
That's impossible.
First of all, it's too complex.
Secondly, the algorithms for proving safety are not linear.
They could be quadratic, for instance.
So it doesn't scale.
And anyway, there's a halting problem.
And that's also the problem if you have runtime values, right? You read read a number from disk and then you use that to index into a container right
that that too but i was doing it the fundamental things yeah so to do static analysis you have to
limit the language written to something that can be analyzed So that's where the rules come in.
And then you have to make it feasible to use the rules by providing libraries so that you have alternatives
to the low-level fiddling that you can't verify.
So my standard example here is there's a lot of code out there
that's pointer comma size.
And the size is, as Timor pointed out, a runtime value which can't be verified.
However, if we use a span instead of a point-of-commerce size,
we can, in many cases, make sure that the size is correct
because we got it from the compiler from an array size.
And we therefore can isolate the cases where the size is runtime,
and we can actually use a check to make sure it's correct.
So there's this three-level stuff in everything I'm doing about safety.
Static analysis, rules to limit the language to something that can be analyzed
and then libraries to help us actually write good code.
We don't want to go down to the lowest level.
And my feeling about static analyzers is that for good economic reasons,
they're focused on finding bugs in arbitrary C code. And that's a hard job,
but it's a different job from verifying a set of rules for using C++. And I believe it is an easier
task, and we can make it easier by better libraries and different rules. it is new and it is somewhat different from what we have in the
core guidelines it's not just safety we we go after other things like bad code but that's a
distraction in the connection of safety so bianna can i just um drill down into this a little bit
more so you gave a good example about the range checking with the span,
if you have like a range, like bounce check span.
But there are examples, it seems to me,
where we can't get away with this approach
without actually modifying the language mechanics.
Like, for example, UniquePointer, right?
UniquePointer is reasonably more safe than RowPointer, right?
Yeah.
But it has some bits where you get like a raw pointer back,
like.get or.release, I think, which we can say don't use those.
But then it also has like operator arrow.
Like how do you do anything with the object inside?
Like anything at all?
You need to use operator arrow, and that gives you back a pointer, right?
So in order to make that safe, you have to
actually change how pointers and references
and operators work. So we would introduce
like a breaking change to the language.
Or maybe I'm missing something.
I'm saying no here.
Okay, I'm very curious about how to make that safe.
The point is,
as I pointed out before,
that you have to check
pointers being used and leaking and such.
And what I recommend doing is actually a static analysis to make sure that you don't retain
and use a pointer that you got from the unique pointer after the unique pointer has gone out of scope or things like
that.
So you can do a lot with static analysis there.
But so what can you do today if you don't have that?
You can actually build safer versions of the standard library.
I have not tried with unique pointer, but you could
imagine a unique pointer with some serious restrictions on get. But I've tried it with
vector. What happened in some very real code is that people have a vector, they pass it to another thread, and then somebody does a pushback that relocates.
And one of the two versions of the vector is now invalid.
And we didn't have the static analysis software to prevent that.
I think I can explain how this can be avoided.
I think it's under the rules of the
core guidelines, it can be completely avoided. But we didn't have the static analysis software
through it. So what do we do? We build a vector at inarray that's also in the GSL support library
that simply doesn't have the invalidating operations.
So I can give you a pointer, but you can't do a pushback.
And if I made it as a DIN array as opposed to a vector,
then I can't do an invalidation either if I don't trust my own software
to follow the rules.
And the bug went away.
This happens repeatedly.
It was very subtle bugs, and poof, they went away.
Similarly, there has been subtle bugs in large code bases, pointer, comma, size,
that when changed to span, the GSL span, poof, they were caught.
So you can make significant improvements without having the full profile stuff.
And I'm actually thinking about now what can be done as a subset of the core guidelines, a subset of the profiles, which we would call
profiles light, that can be implemented without serious static analysis.
Perfection requires static analysis.
But hey, we're engineers.
What if we could get almost all of it without going in that direction? It wouldn't please the
NSA, but it would please a lot of people who has the right reliable software. You can reduce that
kind of bugs. And so I'm wondering, can we build something, profiles light, that takes the low-hanging fruit,
takes the thing that a compiler can do with its current knowledge of code
and eliminate the problem.
And that takes some thought.
It's very preliminary,
but I realize that it will take too long to get the full-blown profiles in place
for a lot of people.
They want the solution now.
So how do these profiles differ to something like just adopting an existing, let's say, safety-critical standard like MISRA, for example?
Because something like MISRA traditionally forces you to write low-level code.
And secondly, it doesn't provide guarantees.
It is more like when I talk about profiles light.
That is, it takes away some problems.
But traditionally, it forces you to write C-like code.
There's some good work being done on concurrency.
I'm actually in a meeting about that tomorrow.
No, Thursday.
But about getting concurrency rules in that would be joined with MISRA and core guidelines.
Right.
And so what I'm talking about here, safety is not the only thing,
and safety is not my only focus.
Of course, yeah.
We will dig into some other things after our sponsor break, I think.
Actually, just one more question before we break for our sponsor.
While we're talking about making C++ a safer language,
what do we think about some of these so-called successor languages
like Carbon, CPP2, Val?
Yeah. First of all, I'd say I'm actually aiming for making use of C++ safe,
not just safer.
Provably guaranteed safe.
That's what we're aiming for.
Not for all code, but for some.
Secondly, there's always been wannabe successor languages to C++.
Remember Java?
There's been dozens.
I think the current wannabe successor languages are born out of various forms of frustration, partly that the C++ Standards Committee has trouble focusing and
has trouble delivering things quickly.
And if it delivered things quickly, they'd probably get a lot of things wrong.
It's 200, 300, 400 people trying to agree to things.
That is difficult.
And I think a lot of the frustration comes from that.
The other thing is that people always can do the obvious,
which is simplify the language for my use.
And then later, it has to grow and get the facilities
for the full range of things.
When Java came out to take over the world,
I predicted that if it succeeded, it would grow by a factor of three.
I was right, and it got better for it.
But the claim that you always get from new languages,
this is simpler, look, all of this stuff in C++ you don't need.
Well, wait and see.
A lot of the things are there because there was a need for it by a sizable community.
I think C++, in C++, we got the major issues right.
And in retrospect, 10, 20, 30, 40 years later, we could probably get all the details better, but the fundamentals are still right.
Right. So it sounds like you're fully committed to making C++ a safer and simpler language, which is great.
Yes, you can't simplify the language because of compatibility constraints.
You can simplify the use of the language. This is a very important distinction.
Right.
In the meantime, there are plenty of pitfalls and headaches.
So that's a good segue to our sponsor break, because this episode is supported by JetBrains.
JetBrains has a range of C++ IDEs to help you avoid those typical pitfalls and headaches
that are often associated with coding in C++, at least for now.
Exclusively for CppCast, JetBrains is offering a 25% discount for purchasing or renewing a yearly individual license on the C++ tool of your choice.
That's one of C-Line, ReSharper and ReSharper C++, or Rider.
Use the coupon code JetBrains for CppCast, or one word, during checkout at jetbrains.com.
All right.
Thanks, Phil.
We are back here with Bjarne.
And Bjarne, when we talked about what you want to chat about in the episode today, you said that safety and the things that people typically talk about in this context is not the whole picture, right? And also like features like that we add to the language, which don't seem, you know,
at first glance to be directly safety related
are actually part of the picture as well.
So you said we could talk about modules and concepts
and the C++23 standard,
which is now kind of our current one in that context.
So what are your thoughts on those?
Okay, first I'll just add a little bit in connection with your sponsor comment.
Organizations like JetBrains and so on and such, because they have a lot of analysis
ability, are actually important in the context of something like core guidelines and profiles in the future,
because that's exactly the spot where you can make improvements
and also Clang Tidy and Microsoft Analyzer.
This is an area that I think is immensely important.
Anyway, back to your question.
There's more to engineering good systems than safety.
There's also performance. There's also reliability in general, which is system property. You can
write safe programs that happens to give the wrong result. The old saying, if I don't have to give
the right result,
I can make it as fast as you like and as safe as you like.
No problem.
So it's an engineering thing.
We have to balance trade-offs.
Some areas are more critical for certain aspects,
other areas for others. And so we also need a language that is expressive
and has good abstractions for writing code.
And the C++ approach has always been not to solve a particular problem,
but to provide abstraction mechanisms to allow you to solve your particular problem and me to solve mine. And it's that kind of openness and focus on generality
that is actually one of the greatest strengths of C++.
And then you add performance to the mix
and you get this notion of zero overhead abstraction,
which I think is key.
And if you look at modern C++, C++20, C++23,
you get a very different language from, say, C or C with classes,
C++03, as you mentioned earlier.
And we should encourage people to use it.
And the way you encourage people to use it is to demonstrate that it actually makes sense.
And I think for C++20, the important things were modules, concepts, and coroutines.
Coroutines lacked library support, and it's coming, but not as fast as I would like. But remember,
quarantine was what kept C++ alive for 10 years, so Sun decided you didn't need it
for a general view, including me. I was very unhappy about that.
Anyway, I won't talk much about the quarantines because of the lack of the library support. But I'll talk about the other
two. I proposed a module C++, a module STD that gives you basically the whole standard library
as a module to try and demonstrate that you could afford to just grab the whole standard library
and that it is so pleasant.
I've been writing a lot of code recently using module STD, and it is so pleasant.
I don't have to start with 10 or 20 includes.
I don't have to worry about the includes messing with each other. I don't have to remember
in which header file shared pointer is. Yes, I know what it is, but take a student,
they don't know what it is. Take an experiment with interesting parts of C++, and you don't
remember where all those library facilities are.
Or accumulate.
Import STD, it works.
And it's so much pleasure.
And the question about this was not whether it would be nice,
because obviously it is.
The question was, can you afford it?
And I did some small experiments showing that it's about 10 times faster.
So actually, no, it's much more about 10 times faster to actually know it's much more than 10
times faster i think it was 80 times faster to import the whole library than to just include
sgt include io streams and i did some experiments with taking all of my favorite, the most frequently used libraries, about 10 of them,
and including those or importing the whole library. And the advantage in compile time was
only five times. Only five times. But it's still good. If you have a server farm for doing your compilations,
it means that you can sort of retire half or more of your processes.
I mean, tell that to people who want office space and floor space in critical places.
They'd really love it.
It's one of the arguments for C++ and for modern C++
is you don't use as much electricity.
And then I've used it for real for half a year or so.
And it also seems to scale.
I write relatively small programs just now, but the response time is noticeably better. And if you go to larger systems,
you can get all kinds of stuff that you didn't expect with side effects.
Like I had a graphics system that was fine.
Everybody's got a graphics system.
And my code started breaking.
I was using Macs from the standard library, but somebody used somewhere deep in the header
files for the graphics system, there was the Unix, Linux Macs, which was different.
And that kind of problem you can eliminate.
And so I think modules are important in that we can have logically defined
chops of a system defined like the graphic system or the standard library.
And so I can imagine building a million lines of code, including maybe five modules, which are the standard ones.
I could even make a module out of those five modules so that for the project, you have the import project.
And all of these interference problems will either disappear or they will have been dealt with when you
created that module.
And yes, it beats precompiled headers also.
This is not theoretical.
There was a really good talk in CPPCon 2022 by... Was it Daniela Engert? Daniela Engert.
I've been
recommending that a lot
because she shows really what
you can do with modern C++.
It should be shown to all of
the people who think it's a
minor variant of C.
It's a great talk.
Strongly recommended.
I'll put a link in the show notes.
Yeah.
And that was, of course, using modules.
And it used a lot of, a fair bit of concepts also.
I mean, concepts are the part of the template design that I couldn't do in 88.
I mean, I wanted three things.
It's very clear.
Generality, no overhead runtime, and decent interfaces.
I mean, I was the one who got type checking in to see that the original declarations didn't
have argument types in them.
And so I knew the importance of that, even back in the darkest stages.
And I couldn't do all three.
I asked around to practical people, to academic experts and such.
Nobody knew how to get all three.
And now we have all three.
So we can actually write generic code the way it was supposed to be written. And I'm quite sad when people write a lot of code that's template class
T or template type def T or type name T. It's just old. It's like writing with void star pointers.
We see it in the standard library. It has not been properly integrated yet into the
language in the way that it could be. And we should do much more of it. It gets much better.
And of course, it compiles faster because it catches errors. And again, it takes time to get something into the ecosystem.
People have to learn that concepts is the right way of specifying a template
in almost all cases and that there are benefits from it.
Implementers has to emphasize it in their error messages
that hasn't happened yet.
They still think that you want as much information as possible
when you make a mistake.
No, I just want to know that this function couldn't be called
because that type didn't match that concept.
The prototypes that we built 10 years ago
could do that. And there was a switch
that said, I want all the other information.
But the default
is you just tell there's a type error.
A concept error.
And I
think all the libraries should be like that.
And sort of the best interfaces
also comes from
defining, I want to sort anything sortable as opposed to I want to sort a specific type.
That way you avoid a number of indirections for performance reasons.
It doesn't handle the problems where you want a binary interface,
but that's a different issue.
So, if I may,
I have two comments. The first one is
the talk by Daniel Engert that we mentioned
earlier is actually called Contemporary C++
in Action.
So, go and watch that one.
The second comment, I want to drill down a little bit
more into what you said about concepts.
So, obviously
I've been around
when concepts were standardized
for C++ 20,
and I think they're a great feature.
And on the one hand,
it seems like not only do they make
genetic programming easier
and more reliable,
but also they even enable libraries
that you couldn't possibly write
without them,
like something like ranges, right?
It wouldn't be possible without concepts. And I i think a couple people have written versions of it where
it's done with like still unable if and horrible macros but that's not really not really a good
way to do it but um as amazing as concepts are i haven't really seen them catch on very much
in like the libraries that i use like day to day. And I, and I wonder why that is. Like I heard,
for example,
one person saying that they're very wary about introducing concepts to their
library,
because once you define a concept,
like you can never change it again.
And if they got it wrong,
like then,
then that's like a dead end.
And so they're like really wary of introducing them because you can't ever
change them without breaking everybody's code.
Do you,
do you know if that's like a thing,
if there's any maybe other reasons why they didn't really catch on
in like day-to-day kind of library use?
I think we are seeing, by the way,
this thing about never being able to change it again
is based on the assumption that every piece of code
uses every part of the concept
and that you have control over none of the rest of the code,
which is not true even from the person who gave that talk.
Anyway, a lot of it is that people are expert and knowledgeable
about basically the untyped template use, and they like their little traits
or in the standard library, and they want to poison the use of ADL,
which they need if they write untyped stuff
so that the concepts doesn't catch the mistakes.
And so people get to love their bad old ways of doing things.
And I think then they don't say, I don't like this novel thing.
They don't say, I really love to do it the old way and I don't want to change my code
and look, I'm clever.
I can use enable if and read that stuff, even if you can't.
They don't say that kind of stuff, right?
They find some aspects of the new stuff that they don't really like
and they know people don't really understand
or maybe we haven't reached the point where it's well supported in the compiler.
It's like I don't want to use concepts because the error messages don't really get better.
Well, if the compilers haven't picked up on it yet, the error messages don't get better.
But we know they can be better because I did it 10 years ago together with people, colleagues.
So a lot of this is like people get in love with the C declaration syntax,
which is obviously a mistake.
Even Dennis Ritchie knew that a year late.
There was a function of the size of the memory
and the technology of parsers at the time.
A year later, he could have had a linear syntax.
We didn't have the problem.
But people get really, really proud of being able to understand this
and write, for instance, a function returning a pointer to function
without using a type def.
Oh, that always
breaks my brain.
That is why people are proud
of it. If I can do it and you can't,
I'm smarter than you, right?
No,
no, no. It just
means I've been
locked up in some strange
world where that's
surprising.
And I think some of that with enable if and with untyped arguments to templates is exactly that effect.
It's familiar and people are proud of being able to do it.
I think like using the requires clauses directly is like writing a simply code.
Sometimes you have to write a simply code, but boy, it is very rare.
And people who can write it gets overly proud of being able to do it.
I've written a simply code.
I was writing micro code for a while.
I mean, a simpler is for whips.
I've been there.
And I don't really want to go back
because we can do so much better today.
So I think we should really wrap up.
So is there anything else happening in the world of C++
that you find particularly interesting or exciting?
Maybe look into the future.
I would like to see static reflection in place.
And I hope people will get the asynchronous model sorted out.
We've been almost there several times,
and then people get a brand-new idea,
and we get something brand-new in three years' time.
Those two features are really good.
We have been almost there with functional style pattern matching.
Again, people got new ideas
and now they're still trying to pick
two good alternatives,
between two good alternatives.
We should focus a bit more
on actually delivering things.
Perfection is unobtainable,
but get something that's really good
and principled.
Yeah, I got the impression that both pattern matching and static refraction really got set back during the pandemic.
Not a lot of work happened during that time.
We suffered a lot.
When it comes to design, Zoom is not ideal. You really want a few people, not a lot of people, a few people in a room with a whiteboard arguing it out over a day or two.
Yeah.
This has happened again and again.
Major significant progress comes out of a small group of people locked up in a room together with a whiteboard.
It's not the computer. It's not the large number of people locked up in a room together with a whiteboard it's not the computer it's not the
large number of people it's it's it's people with ideas working them out together right
well hopefully we will see some movement on those fronts well we are starting to i think so
hopefully that will keep progressing looking forward to those as well. So anything else you want to tell us before we let you go, Bjorn?
Yeah, don't make statements about performance without measuring.
I hear a lot of that, even in the standards committee.
That's a good one.
Measurement is, of course, hard to do for things that should scale.
But really, people waving their hands,
saying performance, efficiency,
I get very nervous.
I want to see numbers.
And I want to see exactly what they measured.
All right.
Well, thank you so much, Bjarne,
for being on the show with us today.
It was good fun.
I think a very great conversation.
Thank you so much again for being here.
Thank you.
Thanks for inviting me. See you around.
All right. See you. Have a great week.
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 guest or topic, we'd love to hear about that too. You can email all your thoughts to feedback at cppcast.com.
We'd also appreciate it if you can follow CppCast on Twitter or Mastodon.
You can also follow me and Phil individually on Twitter or Mastodon.
All those links, as well as the show notes, can be found on the podcast website at cppcast.com.
The theme music for this episode was provided by podcastthemes.com.