C++ Club - 161. Sanitizers, Cpp2, exceptions, compilers
Episode Date: May 21, 2023With Bjarne Stroustrup, Frances Buontempo, Gianluca Delfino, VladimÃr ArnoÅ¡t, Andrew Fodiman and other colleagues.Notes: https://cppclub.uk/meetings/2023/161/Video: https://youtu.be/WAhBuIhaDLM...
Transcript
Discussion (0)
Welcome everyone, this is Meeting 161 and today is the 4th of May 2023.
First of all, I'm going to start with book news. C++ Book Camp got updated and got another chapter,
chapter 6, Smart Pointers and Polymorphism.
So this is the chapter where you learn how to program your way out of a paper bag, as Fran promised.
Indeed, it's a very important skill and actually quite a nice little kind of go-to problem that I use for various showcasing various things,
including some machine learning algorithms in a previous book
but this one some blobs just move up the screen and some of them in fact all of them managed to
escape the paper bag so we start with some basic blobs always do the same thing which is boring
but it it gets us going and then we mix in something some
blobs doing some random steps so you can erase at the end
yeah so you remind us when the paperback edition is coming out so i'm not a hundred percent sure
it depends how long it takes me to finish writing,
but certainly early next year, if not before then.
I think it's scheduled for Feb next year.
But one can already access partially the book on the website.
Yeah, so if you buy Manning's early access programme,
you've got access to this live book, which we're looking at now.
And you can leave me comments there.
And several people have asked questions or suggested better ways of doing things.
And you also get an e-book copy or a PDF, so you can put it on a device of your choice as well.
Nice. A curious thing I noticed you are using East Const in your
code examples. Oh, force of habit, yes that's a controversial one isn't it? It's one of those
religious wars. Well and some people won't like the brace placement either.
Yeah, I started life with East Const, and I know opinions are divided on this.
I'm a force of habit.
There is no disclaimer in the book explaining why the East Const.
Perhaps I should explain myself in the intro.
Or go through and go West Const, or mix it up and be incoherent,
which would make everyone angry.
Get people used to real code.
Yeah, it's best to be consistent at least per file.
Yeah, yes, quite.
But I found that East Const is easier to explain for beginners to demonstrate how compiler sees it.
Although I think C++ core guidelines prefer Westconst.
Yeah. Fair point. Next up is a new issue of the Overload journal, 174, with Franz's editorial, The Rise and
Fall of Almost Everything.
And it's very interesting.
There's philosophy and there's random numbers, so you should read it.
The next article is Drawing a line under aligned memory by Paul Floyd.
When we allocate memory, we often forget about alignment.
Paul Floyd reminds about various aligned allocation functions. Yes, I've seen this problem in production. We had a very hard-to-track bug
with eigen failing because the memory supplied to it wasn't aligned once in 10,000 locations.
So that was fun. Yeah, Paul Floyd does some pretty hardcore math stuff in his day job,
so he knows quite a few edge cases.
I'm trying to encourage him to write more things for us.
He knows a lot of things.
The article by Andreas Fertig, C++20 Concepts, Testing Constraint Functions.
He says,
Concepts and the requires clause allow us to put constraints on functions or
classes and other template constructs.
Andreas Fertig gives a worked example using how to test the constraints.
Another article is by Lucian Radu Teodorescu, in search of a better concurrency model. He presents current plans for concurrency
in the vowel programming language, comparing them with other languages. And finally, Metaverse
by T.D. Dai. And yeah, it's about Metaverse. Haven't read read it i might need to explain this slightly so
observe this is april's edition so usually chris oldwood writes something more kind of general
high level for the last article but every april we have a kind of april fall from well i believe
she pronounces her name tdd so you've got a test driven development
all right going on there and it's usually a skiff on something current so this time she's decided
to vent her fury on the metaverse and all things ai so that that's an april special every april
there's something silly from TDD. Nice.
It's been a tradition for a while.
Nice.
Right.
Next, one update about the do expressions paper.
This is the proposed syntax.
It's an expression that starts with do.
There are curly braces, and then you do
do return inside, and that has its own type, but it's not quite a lambda because it doesn't
introduce a new scope. No, it does introduce a new block scope, but it does not introduce a new function scope. That's the thing.
And the interesting update about it was that it was discussed in UG and there were a couple of polls. So the first poll was UG encourages more work in the direction of do expressions
as presented in the proposal. And there was consensus about this. So that was good. And the second poll was, interestingly, UG prefers
the result of the do expression be last statement, a la GCC statement expressions prohibiting
early return from a do expression. And that got consensus against, so I think that's also good.
I like early returns and don't like artificial constraints about returning early from a function.
I think Scala has a notion of the default return from a function or a block, which is the last
statement. The value of the last statement is the return value. But I think it's good that we
didn't get that. Next up is this paper. It's quite a long one, we're not going to go through it in its entirety.
The title is Don't Look UB, Exposing Sanitizer Eliding Compiler Optimizations.
And that was kind of a public service announcement, because according to this article, if you build your sanitizer builds
with optimization turned on, the optimizer may remove bugs that would otherwise be detected by the sanitizers. We, for example, we build, usually build at
02 or at least 01, because otherwise running sanitized builds is very slow. And that's how
the sanitizer documentation states that you should use optimization
at least one, otherwise it will be too slow.
But turns out that that might mask
some bugs, and that's
useful to know for anyone who's using sanitizers.
That's a problem they have with contracts also.
You have to be very careful how you specify a condition in a contract
so that it doesn't get eliminated.
And there seems to be some reluctance to restrict the contract predicates to avoid this problem. But it's a
well known problem. Maybe not in the context of sanitizers.
So our sanitized build tests in one project, they take maybe two hours to run. And when I turned off optimizations and
tried to run it, it took about two days. So that was... But it did detect quite a few problems that weren't otherwise visible. Or maybe I just
should have run the sanitized tests more often. I think a lot of those problems can be
detected statically. But of course, if you avoid sort of various antique programming styles, people don't.
One of the bugs detected was an uninitialized Boolean variable, where Ubisan says,
well, this random value is not valid for Boolean. I guess that could have been detected by a static analyzer
used before initialization.
Yeah, it can.
Or if you're getting really simple-minded,
like the core guidelines, it will simply
reject it for not having been initialized.
Yeah, that's true.
I mean, sometimes you just have to be simple-minded to be efficient, and it gets in the way of some cases and some old habits, but you can make the problem disappear much more easily than all this cleverness.
Yeah, I still need to turn on Clang tidy for many of our projects.
This is the reddit thread about this, some examples and yeah, keep that in mind.
And this is another in-depth article by Fangrui Song, who describes how sanitizer interceptors work,
with lots of useful information on implementation.
And yeah, that's useful to know for anyone using sanitizers.
I mean, it's not necessary to use them, but it's useful to know how they work,
so that it's not like... it doesn't appear to you as magic.
Cpp2 spring update from Herb Sutter is the next topic. He says since the year-end mini update,
progress has continued on Cpp front. There is a link to his announcement video in CppCon
2022. He says, quote, this update covers acknowledgements and highlights of what's new in the compiler
and language since last time, including simple mathematically safe and efficient chained comparisons. Named break and continue.
Simple and safe quotes starts with main. User defined type including unifying all special
members member functions as operator equals. Type namespace function object aliases.
Header reflect.h with the start of the reflection API and the
first 10 working compile-time meta functions from the proposal, p0707. Unifying functions
and blocks including removing colons and equals from the for-loop syntax. There is a long list of contributors that Herb acknowledges.
And then he goes through all the updates.
Now this one I really am not sure about.
I mean, maybe it's me, but I've never used chained comparisons.
And if you encounter something like this in code, I mean, it does look a bit confusing,
doesn't it?
I would agree.
I would leave a bad comment on the code review.
Yeah.
I mean, I guess mathematically you can do it, but why?
There is a proposal by Barry Revzin chaining comparisons, which means someone needs it.
Okay.
Named break and continue.
So you can continue to a label or break to a label.
Some sort of go-to? Yeah, go-to on steroids. Go-to with extra steps.
A new signature for main, which just has a single parameter args, and that's a container.
So he says, quote, yes, this is really is 100% C++ under the covers.
As you see, as you can see on Godbolt compiler explorer, just nicer, in quotes.
And the bullet points are the entire C++ standard library is available directly with zero thunking,
zero wrapping and zero need to include or import. It's just automatically there. Convenient defaults, convenient semantics and services,
and type and memory safety by default. I also listened to the CppCast episode, Cpp2 with
Herb Sutter, which was published on the 31st of March 2023.
And that was very interesting.
Timur and Phil asked lots of interesting questions, and Herb is always interesting to listen to.
For example, he says Cpp2 is to C++ as Swift is to Objective C++.
I'm not really sure about this. Does he think that Swift is based on
Objective-C or it generates code in the same way? His example is that in later iterations of
Objective-C there was a construct introduced, a concept introduced of ARC, automatic reference counting,
which significantly reduced boilerplate code you need to write to manage memory.
And that's sort of, kind of what Swift does under the wraps. But other than that, to me, Swift looks like a different language.
I think he had a slide in his presentation and he was presenting comparisons of languages and
some of them were just quote-unquote the evolution of a previous one, like JavaScript and TypeScript, and maybe Objective-C and Swift were also on that.
So it's as a metaphor of kind of an evolution,
evolutionary step at least towards something.
I suppose.
I think it's a stretched metaphor.
Yeah. a stretched metaphor of sorts. Yeah, he also said that TypeScript
could take any JavaScript code and compile it and it would be valid,
which is not the case with Swift and Objective-C. And coming back to Cpp2, the more
progress it makes, the more it looks to me like a different language.
I predicted that. It's inevitable.
Yeah. I can totally understand this. He says it's a personal experiment, and
I'd imagine as you work on something like that, you want to modify more and more things, and so it diverges more and more from the original syntax that was supposed to be slightly better into something that's completely
different. I mean, it generates C++, and Herb specifically said that he worked, he tried to make the generated code look nice, as if it was written
by hand. But still the divergence is growing, it seems to me. And although he says it's just a
personal experiment, there are already lots of contributors and lots of enthusiasm and
big expectations. So yeah, if you read the reddit thread, there's lots of enthusiasm.
Although some say that, yeah, Cpp2 just looks really ugly to me, so I guess it's a matter of taste.
Or maybe, like you've already touched this thing, I think you Gianluca said that someone's
bound to not like some aspect of it. And that will be the sort of a sticking point. And if Herb is not willing to
change that, then the number of people who had great expectations and then were disappointed
will grow. He says it's really simple. I mean, he did say that, and that's a trigger for me. It means it's
never going to be simple. It's simple for the author, I bet. But then, not only you need to know all the quirks and details of C++. You also need to know
CPP2 and how that does things on top of C++ and what bugs that introduces. I mean,
you're not expecting CPP2 to be completely bug free, right?
Well, all new languages are advertised as being really simple.
I remember when they were doing Java presentations where they were bringing the ARM, which was the document for C++ at the time, and in stage, you're ripping out out pages saying this is what you don't have to know this
is what you don't have to know this is what you don't have to know um that's sort of the model
of introducing a new language you you don't have to know all of this you don't have to learn all
of this you don't have to hire programmers that are experienced you can get anybody to use it because it's really simple.
I'm maybe exaggerating a bit,
but do you recognize that technique
of getting a new language,
getting interest for a new language?
Yeah.
So you should expect it.
This also contradicts somewhat the idea that we should be preserving a nicely formatted, nicely readable generated code. Because why would we have to bother generating nicely readable code if in the end we don't have to
read it to inspect what's going on so if we do want to keep a nicely generated code it's probable
because we need to actually take a look under the hood which means we kind of need to know both of the languages. I may be guessing, but I think his motivation may be that if you use Cpp2 and
then it suddenly disappears for whatever reason, the experiment fails for example, you still end
up with somewhat readable C++ code that it generates. I see. Apparently you can mix Cpp2 and C++ entity by entity in the same source file.
That's gonna be fun. For example, he says a colon always means I'm declaring a new thing
and it has no other meaning. So presumably Cpp2 parser sees those declarations as part of Cpp2 and
replaces them with the generated C++ code.
Herb's proposals in the last seven years came from Cpp2 work.
So I expect Cpp2 will have metaclasses before long.
In the podcast, they talked about Vittorio Romeo's epoch proposal.
And Herb says that it's an interesting idea, but on the other hand, he would like fewer
epochs.
I think he said he wants one epoch.
Yeah.
Which I don't understand, you know, because if you do want to have one, then...
Maybe he did mention that he wants one every 10 years or so.
Once in 30 years opportunity, he said.
30 years opportunity, he said. 30 years. Because I think he meant
a single epoch that he wants
to introduce
breaking changes into C++.
Maybe reasonable,
I'm not sure, but
certainly
an opinion that is going to steer some
emotions.
Definitely.
And presumably this is what he thinks about Cpp2 experiment.
Yeah, that's the new epoch. Maybe.
Well, we'll see. Definitely something to watch. The comment thread for the podcast is also interesting to read, also quite a
lot of enthusiasm. This Reddit post says, if exceptions were zero cost from the
very beginning, would you have designed your libraries or app differently?"
And the poster says, I'm an exception lover, but I don't use it as much as I would want to use it.
But I've been recently thinking, if I did use exceptions as much as I wanted to,
with no worries, how would i have written my code different basically
they say if exceptions were zero cost i'd probably end up using them as much
or maybe even more than if and else blocks or other control statements
and i'm like no that's not what they were designed for.
I mean, an if-then-else is just much prettier than a try-catch-for-starters.
Yeah, and you're kind of moving towards just doing go-tos at that point,
trying to follow how you've ended up over here from over there.
It's just like, ouchouch i'd rather not myself i think a lot of exception fear
is just fear and rumors if you use them reasonably they essentially never triggers
unless there's something really wrong and they are dirt cheap if you don't throw.
That's what they were designed for, which leaves the problem. If you have so little memory that you can't have an exception handling mechanism without crowding out utility.
But that's a different issue.
If you have a real computer, just use
exceptions. That's what I do. But if you see a lot of try blocks, there's
something wrong with your code. Yeah, this is also the consensus of the thread in
general, I think. Also, there's been some measurements about what they cost and very often people forget
that if you don't have exceptions, you get a lot of ifs and elses or you get these
fancy features for dealing with errors which hides the ifs and eles, you get multiple threads anyway.
So yeah, in most cases don't worry about the cost of exceptions, but don't throw thousands
of exceptions in quick succession either, as was the case in one of the benchmarks that decided
that exceptions were very bad because a thread throwing thousands of exceptions in a quick succession was slow.
Yeah, I can be slow in many, many ways. How about a near infinite loop doing essentially nothing?
Or we had a case where C++ code interfacing with Java code appeared to be very slow because Java code used exceptions for flow control.
So that was also misplaced blame.
I mean, look, one of the things that was said very early on with exceptions was they are
not for flow control.
We are not using them to terminate loops.
This is not Algorand 68.
This was found to be a really bad idea 40 years ago.
I think we have a marketing issue here.
Exceptions at BetPR.
And then you have people littering their code with a noexcept, turning exceptions
into terminate. Obviously, embedded platforms are a special case when there's no heap or
there are hard no throw requirements. So I can sort of understand that. Hard no-throw is rare, actually.
But if the implementation mechanisms for exceptions crowd out functionality,
or if error handling has time constraints,
those are the places where you start worrying about exceptions.
Microsoft has published an article titled
Modern C++ best practices for exception and error handling.
And the first chapter in big letters is use exceptions for exceptional code.
So yeah, worth reading that. I wonder who wrote it.
It's not original.
It doesn't say who is the original author.
Yeah, 8 contributors.
Right.
Some compiler news now.
GCC 13.1 was released.
This is the announcement.
And it says, quote, the C frontend got support for several C23 features.
The C++ frontend for C++23 features. The C++ standard library experimental support for
C++20 and C++23 was enhanced. So, C++20 is still considered experimental in this GCC
version. There's still no modules, although there is some progress, apparently.
And I'm not sure about format.
There was an announcement earlier that this version, version 13, was supposed to get C++20's
format support.
So maybe it is in...
I haven't checked actually but
if not
you can always use
the excellent
FMT library
from Viktor Zverovich
it's really nice
okay
next up is
an article by Chris Wellens
titled
my favorite C compiler flags during development.
I realize it's not strictly C++, but the flags are pretty much similar.
So I think it's relevant.
He starts with this quote.
The major compilers have an enormous number of knobs, which is true.
There's lots of switches and parameters to customize.
He proposes a few useful warnings to enable, and luckily also not only for GCC and Clang,
but also for MSVC, which is really useful. And obviously a similar baseline
for MSVC to WALL and W-EXTRA is compiling your code at warning level 4. I remember I had to fix an enormous amount of warnings before switching from level 3 to level 4.
And if you enable all, then this STL doesn't compile in MSVC, so
level 4 is the best you can do at the moment.
So yeah, very useful article that you can use his suggestions right away.
And discussions of this article on Hacker News and C programming subreddit, which also
have lots of good suggestions. Right, next up is Matchit, a lightweight header-only
pattern matching library for C++ 17 with macro-free APIs. As we're all waiting for
pattern matching to land in C++ 26 hopefully. I guess if you are eager to use matching, you can use this library.
I think it... oh, right, it has an Apache license, which is permissive, and it supports Linux, Windows and Mac OS.
Is there an example?
Yeah, I'm just scrolling to it.
I think there are quite a few.
So this is one example.
There is a function match that has sort of two sets of parentheses.
One is the first one,
you enclose the variable that you're matching.
And the second one contains patterns
with some weird syntax,
including pipe symbol.
And they look quite readable, I would say.
And there are facilities for more advanced matching.
Like you can match by class name or by type or by value.
This is where I have a question.
Look at that as circle, as square.
Do they check them one at a time? Or do they do a virtual core?
Building things like this, and they ran very slow, they look pretty. But you get in tests,
and they're dynamic tests. I think it's done dynamically. The author says Oclass's dynamic cast is used by default for the as pattern, but there are
some customization points.
It's reasonable.
If there's 50 alternatives, you've just done a major, major hit on your performance.
This is easy to do.
I had students do it 15 years ago, but I rejected it for cost.
Right. Yeah. There is an article in the same repository that illustrates,
it compares this library to a pattern matching proposal.
And there is also another article that compares this to the rust pattern matching.
So yeah, maybe as an experiment, or if you do some benchmarks for your own use, maybe you could use it.
It looks familiar to Lex and Yak, a long time ago,
that I used to see, like this pipe. Yeah, pipe is appearing in more and more proposals these days,
even like some sort of a pipe operator. There are things like matching tuples, matching variants, matching polymorphic types, which
happens dynamically as we just saw. Evaluating expression trees even. So I suspect you can
write a very complex matcher that probably can run some program.
There are wildcards and yeah, so it's quite an extensive set of matching available
for this library.
Together with a student wrote a pattern matching system
a long time ago.
It was littered with macros, but it had the interest
in property that it ran as fast as Haskell and other languages like that where it built
into the compiler. It doesn't seem to be that a lot of these proposals actually worry too
much about portability and they don't worry too much about integration
with the rest of the language.
This creates a problem because people who are interested
in the whole language and more than one thing
don't have as much time as entusiasts for a particular proposal.
Yeah.
I wonder how things are with the actual
pattern matching proposal by Michael Park.
I haven't heard much.
Right.
Next up is Clang 16 documentation.
It was just released and there's a link to
some C++ changes. C++ 20 features got supported, some of them. Some bug fixes for C++ 20
features. And I think Clang has more advanced support for C++ modules than GCC at this time.
Right, so this is LVM 15 release. And this is the reddit thread.
There is an interesting built-in function in Clang 15 starting with clang... no, it started earlier,
but in clang 15 it got a nice update and it's called double underscore built-in underscore dump
underscore struct. So this is a useful debugging feature where you can pass a structure and a function to print it, like printf, and it will output all the
structure variables and values, which is the go-to library
for networking, because yeah, standard networking is probably not coming anytime soon.
Interestingly this Boost release and the next 183 will be the last releases offering
C++ 03 support for many of the libraries.
About time, I'd say.
And the related article, the related post on Reddit.
Has Boost lost its charm i mean charm is probably not the right word but if you need it
you can use it it's got lots of useful stuff but also be prepared to pull in like a ton of other
stuff that you don't use if you use just one thing and that's part of the problem once you've pulled
it in you find that somebody in the organization
will use the bits that you weren't planning to use. Yeah. A quote from the thread.
Since C++11, Boost has shifted from provide actually useful basic containers because the STL is shit, to provide cool quality stuff
that is widely useful but out of scope for the STL. See things like flyweight, spirit, log,
multi-precision, safe integer, ASIO. Boost is still a wonderful library collection. So, yeah.
This is an interesting article called a general overview of what happens before main.
It's a low-level explanation of how a C or C++ program's life begins before the main
function is called. And this is especially useful for those
working with embedded platforms, but is also interesting to know for any C++ programmer.
What happens before the start function is called? That is, the start is the entry point and before main
it's called before main. And there was also a talk by Matt Godbolt called in CppCon 2018 called
the bits between the bits how we get to main. It a very good talk. That's pretty much all his talks.
Next is a lighter topic. Dan Potts writes on Mastodon, quote,
This is your periodic reminder that 10 years ago an audiophile forum started debating which versions of memcopy
had the highest sound quality. And that C++ new sounds better than malloc.
Is this for real?
Yeah, apparently. I went to the forum and this is the post. one of the posts, it's like a long thread. This one says,
playing WAV files from a RAM disk gave best sound, then moved on to memory play. Initially,
sound quality was worse. Found that the function called memcpy was the culprit.
Most memory players use memcpy, and this is one of
the reasons why memory play sounds worse, like digital sounding. Fortunately, there is an
optimized version. Using this version removes the hard edge produced by memcpy. Also, most players use malloc to get memory, while new is the C++ method and sounds better.
A dimly related topic.
I remember somebody giving a lightning talk at a conference years ago, and they transformed
the compiled output, I think it was, from various different programming languages or just the
text of the code into the sounds somehow and just played all these noises at us and the audience had
to guess which programming language it had originated from from all these weird beeps
and we actually got it right sometimes i can't remember how they'd encoded it, but that was good fun. The very long ones was probably a template error.
I remember someone came up with this debugging technique, I think, in the
iOS programming, which sometimes is difficult to attach debugger to or something. So they came up
with a technique where they played a sound in some
places and different sounds gave you different diagnostics that you could guess. But this
is just something else. I mean, I didn't even suspect that Nihu sounded better than MemCopy
and Malik.
I guess it's a question for Timur. He used to work in audio world. And I mean, I think it also
makes fun of, you know, some of the audio fidelity people also are, you know, sometimes known for
being pedantic or crazy about stuff that doesn't always exist.
Sometimes, yes.
There could be software with the audio quality.
Like if your hardware is of such poor build
that there is electromagnetic interference
actually going out of your speakers,
then using different code sequences
actually may affect this noise.
So yeah, but I would suggest using a bare-shielded
equipment rather than changing your code. If you want something of the same, go to Amazon
and read reviews of the audiophile cables, audio cables, with deoxygenated copper wires or something,
and wires trained on classical music.
So one wire costs about $7,000, I think.
And one of the first reviews was like,
someone said,
when I bought this cable and played my music through it
I heard angels
singing to me
anyway
interestingly
also discussing ethernet cables
like copper free network cables
for network streaming
and the quality of the digital data
yeah it's totally bonkers for the classic network cables for network streaming and the quality of the digital data.
Yeah, it's totally bonkers.
For the classic music, the voltage is also very important.
They have the spatial voltage stabilizer to make sure the sound action.
It's very expensive though, for the amplifier. Of course. I remember the blind test where audiophiles were exposed to music played through
very expensive copper wires, and the other one was played via a coat hanger,
and no one could feel any difference. But in this case, actually someone came up with a plausible reason for
this. Someone says, quote, I'm disappointed by the arrogance of users on this forum. I've
never had great luck being 100% confident about the behavior of code without running
it. But in this case, reading the actual code posted will show you that using a bad mem
copy could have potentially caused a problem with audio quality.
TLDR, bytes are bytes, but the link to post is actually about latency, not data integrity.
I think it was about the feel of the sound, not...
I mean, an audio file exposed to chopped up sound would probably end the experiment right
there. But I think the original forum was exactly
about the supposed better sounding, warmer sounding Operator New. Anyway. Right, the last one
is from Mastodon. it's by Isaac Freeman, quote.
The worst thing that ever happened in software engineering was when Kirk asked Scotty how
long something would take and Scotty said 30 minutes and Kirk said you've got five and
Scotty got it done in five and depressionable children watched this and grew up to become
managers. Right, I think that's it for today. Thank you very much for coming and and grew up to become managers. Right.
I think that's it for today.
Thank you very much for coming.
And I'll talk to you soon.
Bye-bye.
Thank you very much.
Thanks.
Thank you.
Thank you.