C++ Club - Meeting 149
Episode Date: June 29, 2022Notes: https://cppclub.uk/meetings/2022/149/Video: https://youtu.be/EoQb39zWP94...
Transcript
Discussion (0)
Welcome to C++ Club Meeting 149.
Microsoft has released a new version of Visual Studio 2022, 17.2.
For C++ developers, the main highlights are module support for CMake.
You have to specify std c++ 20 or std c++ latest switch
and use a misbuilt generator for CMake instead of Ninja.
Another interesting feature is inline hints that have been available for CLion and ReSharper for quite a while now.
But now they come to Visual Studio. This is very convenient to see if you want to see a deduced type for your auto variable
or see the function parameters.
There are also some improvements for embedded developers.
Another new thing is that STL completes C++20 support. And this is true for two versions of Visual Studio,
the newest Visual Studio 2022, and also Visual Studio 2019, version 16.11.14.
Those version numbers are crazy. So this includes several proposals approved as defect reports by the standards committee.
Next, we look at this article by Julian Jorge,
which is comparing memory sanitizers.
The author compares address sanitizer and Valgrind
and also products that I didn't know about,
notably Dr. Memory,
which is apparently an open-source LGPL-licensed memory error analyzer, and Intel Inspector, which I think
is a free tool as well. It's sort of a tool to analyze the built release binaries, not an instrumentation tool like address sanitizer, for example.
The author used a set of buggy programs with a set of sanitizers, which interestingly included
memory sanitizer from Clang. Normally, for best results, you would want to rebuild the entire standard library and any dependencies
to use memory sanitizer efficiently and avoid false positives.
But the author didn't seem to do that.
He ran the test set on several different OSes and hardware configurations and produced a
set of benchmarks.
His summary is as follows. Quote, the less efficient tool on this test set is memory sanitizer,
which finds only two errors as also reported by other tools. As I said, this
could be related to the fact that he didn't rebuild dependencies.
He continues, AddressSanitizerX is excellent. Its impact on the execution speed is low.
It finds many errors, including errors not found by the other tools.
Valgrind and Inspector 2020 are as good as each other.
They find the same errors, including errors not found by Address Sanitizer.
Both are also very slow in the same order of magnitude.
Inspector 2020 is the only good version of this tool. 2016 and 2017 could not manage to
start the test. 2018 and 2019 report an error on the test where there is none. When running the
tools on non-toy use cases, the program ran 3 to 13 times slower with address sanitizer and 163 to 565 times slower
with Inspector or Valgrind." In the end, the author says that they switched to Valgrind in
the SEI from Intel Inspector.
I mean, why not a dress sanitizer, I wonder, given this conclusion.
My guess is they wanted to check the existing release build and avoid having to produce
a new instrumented set of ASAN options that you can use.
GCC 12.1 released.
Quote, the GCC developers are proud to announce another major release, GCC release 12.1.
This year we celebrated the 35th anniversary of the first GCC beta release, and this month
we will celebrate 35 years since the GCC 1.0 release.
End quote.
The main highlights of this release are initial support for CTF debug info format.
It looks mainly relevant to C, not C++. CTF is compact C-type format.
Improved C++20 support. Still no modules, though. And improved experimental C++23 support. Still no modules though. And improved experimental C++ 23 support.
There is an article on the Red Hat blog which outlines the new C++ 23 features
in this version of GCC, like for example if const eval,
auto x, which allows auto in a function-style cast, the result of which is a pure R value,
non-literal variables in constexpr functions, multidimensional subscript operator. I know some graphic programmers waited for this.
The new preprocessor directives
elifdef and elifendef
extended init statement
and some other corrections and internal improvements.
Another new thing is that vectorization is now enabled at minus O2 optimization level.
This is since GCC 12. And another interesting feature is that now it supports the Mold Linker by default.
The Mold Linker author Rui Ueyama tweeted.
This is the first version to support FUSLD equals Mold to use the Mold Linker.
It's a bit funny that GCC now has a dedicated
command line option for my mostly single-person open source project. To be
fair, it's a pretty impressive project and is probably going to be pretty
significant.
There is a full set of changes on the GCC website, including a separate section for C++.
There is a Reddit thread on this GCC release.
The Redditors are unhappy at the lack of modules progress and the absence of support for std
format and std chrono calendar support.
From the thread, I gathered that it looks like Nathan
Seedwell is the only developer working on GCC module support.
The whole compiler and language development situation is a mess, a Redditor says.
Quote, it's always been bizarre to me how, despite C++ being one of the most incredibly widely used
languages,
the amount of manpower available to the language and ecosystem seems to be relatively low.
Even the whole committee process is all done by volunteers
with very limited time.
It's strange.
Tristan Brindle says,
I do find it quite strange that given the amount of money
in the C++ ecosystem, big tech,
financial firms, etc., and given the increased developer productivity that would result from
faster compile times, no one seems to be making modules a priority. Everybody wants it, but no
one wants to pay for it. But Google or Apple could probably recoup the cost of a developer over the course of a year
just in power savings for making WebKit and LLVM compile faster.
Regarding contributing to GCC development, this Redditor says,
I'd love to contribute, but the last time I browsed the GCC source code, I opened a portal
to hell. And regarding Google's contributions to compiler development, another editor says,
folks here have said that Google stopped contributing to Clang so much once they
couldn't get support for changing and breaking the ABI. Now they do stuff with libraries like
Abseil instead. They've also been doing a bit more with Rust. So yeah, not very encouraging.
This is another thread on Reddit about new C++ features in GCC 12, which starts with Modern C++ is becoming so good, it almost feels wrong when you
experienced C++ 99 and prior, getting such
high-level features while keeping the performance and everything. Love it.
Next step is to get proper dependency management, and
we are golden. Yeah, about
that.
Right, next on my list is Lexi, a C++ parsing DSL.
Jonathan Muller wrote this library called Lexi.
It's a parser-combinator library for C++17 and onwards. It allows you to write a parser by specifying it
in a convenient C++ DSL, which gives you all the flexibility and control of a handwritten
parser without any of the manual work. This is an example IP version 4 address parser. Lexi is similar to other peg parsers, like Boost Spirit. The
main difference seems to be that Lexi doesn't do any implicit backtracking,
thus giving the programmer more control over parsing.
There is a nice online playground that the author created, where you can define a grammar and try parsing
a bunch of text using that grammar. And what's interesting about it is it shows you
the sort of a tree that is the result of parsing. It's very interesting. It's a bit slow though. The library is on GitHub using BSL 1.0 license.
Next on my list is C++ debugging in Visual Studio Code.
A new article dropped on the Microsoft Visual Studio blog, in which Julia Raid describes C++ debugging support
in Visual Studio Code.
The main news are there is now a native support
for Apple's M1 chip,
data breakpoints when debugging with GDB,
which is really cool.
There is a caveat.
As it uses hardware breakpoint support,
the number of data breakpoints you can have at any one time
is limited to around 4.
Depends on the CPU.
Another nice improvement is a quick run debug button
that allows running debugging a single C++ file without having to edit
launch JSON file. Editing that file is not a big deal, but if you can avoid
it and just run a snippet of code that's very convenient. Nice to see improvements
to one of the most popular code editors which is now closer to a full-fledged IDE.
Here is a useful tip from Victor Chura. He says, I've been using cpp-reference.com for years,
and just a few weeks ago I found out there is an advantage to actually creating an account.
You can filter different versions of a particular function,
data structure, or algorithm based on your target C++ version.
That can be really useful when you are limited to a particular C++ standard.
Next is one of those articles on Reddit. Currently, what are some of the worst things about C++? Main points from the thread. I won't scroll it because it's a lot. Those threads usually are long
and have various sub-threads that are useless. But the main pain points are, as usual, setting up build tools and system, especially for a new cross-platform project.
In other news, CMake Init is a special tool to initialize a new CMake project.
And that tells you something about the usability of CMake.
You need a special third-party thing to make it easier.
Backward compatibility, which is also a best thing.
ABI stability, or in other words, if only we had epochs like Rust.
Bad teachers, bad books, bad tutorial sites run by content farms and bad videos resulted
from Dunning-Kruger effect.
C developers who constantly shit talk C++ features as if someone is going around putting
guns to their heads and threatening to take away C.
Long build times, lack of built-in package manager, header files, lack of Unicode support,
slow standardization process, the amount of pitfalls that you have to remember to avoid.
Quote, it's baffling to me that you can write ill-formed code that may or may not give you
any errors at compile time, and the program may do something, but what it will do is undefined.
Another quote.
People who complain about C++.
Also the enthusiastic Rust people who show up on C++ fora.
Rust is its own thing, better in some ways and not as good in others.
And the winning comment is, quote,
The worst thing about C++ is the monthly
What do you hate about C++ thread here on RCPP.
I agree.
Next is an interesting thread on Reddit.
Started with a question,
What's your favorite way to crash your application?
Interestingly, his example is not guaranteed to crash, as we saw earlier. Dereferencing a
null pointer is undefined behavior and not necessarily a crash. As another Redditor says,
I've worked on at least one platform where writing to address zero does not crash the program.
The optimizer is also free to remove memory rights that are never referred to later.
And they say that should crash just about anything. It's a bit of code to unwrap, actually,
despite the fact that the editor says most of the time I'm boring and use std abort,
his code snippet is interesting.
He chose the Avogadro number to divide it by zero.
They explain all the choices later and this is a quote. It's well known, the Avogadro number, it's well known and
has nothing to do with systems programming, so long as the program itself doesn't have anything
to do with chemistry. It's a sign that something strange is going on. It's too large for the
compiler to emit it as an immediate, so it must be loaded from the data
segment. It's a floating number, floating point number, so x86 can't divide it with idiv instruction.
It has to get transferred to the FPU or SIMD unit. And they're really picky about alignment, so the addition will bomb. And finally, the goal
here is to crash even if FP exceptions are disabled, by forcing a bad memory access that
the compiler can neither inline with immediates, nor elide because it's marked volatile, with the
optimizer turned on. Doing just what the original poster did
will often be removed by the compilers running with optimization. There are some
other choices in the thread, namely std terminate, std abort, std raise seekterm,
std exit-1 and the compiler built-in equivalents of exit there is also like a deferred
crashing which is a piece of assembly where you trap function with the added bonus, which is
this produces a 2-byte UD2A instruction on x86-64, and the attribute prevents optimizers
from merging it together, so you get distinct source location in your crash reports.
And this snippet that you see works, or rather crashes, on ARM microcontrollers even before
the memory is accessed.
They say LSB is 0, which means trying to enter the deprecated ARM state.
This will crash the CPU before even trying to access the deprecated ARM state. This will crash the CPU before
even trying to access the memory at address 2. Some commenters suggest using
assembly int3 instruction or debug break function built into compilers, which
breaks into debugger or crashes if there is no debugger. And the winning comment was at the beginning of the thread, quote, just running it usually
does the trick.
Next we'll see a library for game development, which is called Box2D.
It's a feature-rich 2D rigid-body physics engine for game programming.
Quote,
It has been used in many games, including Crayon Physics Deluxe,
which was the winner of the 208th Independent Game Festival Grand Prize.
Box2D was created by Aaron Cato of Blizzard, soon to be part of Microsoft.
How did that happen? As part of a physics tutorial at the Game Developers Conference.
There is a fair warning on the documentation website.
Quote.
Since Box2D is written in C++, you are expected to be experienced in C++ programming.
Box2D should not be your first C++ programming project.
You should be comfortable with compiling,
linking, and debugging.
Box2D is on GitHub
under MIT license. It builds using
CMake on Windows only
with Visual C++
and can be installed via
VC Package Manager.
Ports are also available for Flash
What's Flash? Java, C-sharp and
Python. It has its own subreddit and a discord server.
So if you're trying to do some simple 2d game development I guess that is one of
the options. Right, let's look at some more UB.
Just yesterday, I think, Colby Pike, who is also Vector of Bool on social media,
wrote this article, Mysterious Memset. In it, he illustrates the effects of UB on compiler optimizations. Consider this simple function. It takes a pointer to a count, which is int.
The detail is important. It has to be a pointer to the count.
The second argument is a reference to a string. Then there is a loop where all elements of the string are assigned 0. He says
if we feed this program to an optimizing compiler the machine code is roughly equivalent to the
following. It pretty much just checks if the count is not 0 and the rest is as you'd expect. Now, if you do this change,
if you use not std string but std u8 string,
which uses new char8 underscore t character type,
what happens then?
This happens.
The entire loop is replaced by a memset. But how?
What happened? He says spoilers below, spoilers below.
To summarize, this is because assigning two elements of a std u8 string cannot
affect the passing count, the passed count. The reason for that is that
previously in the normal string, its type is a pointer to char, which has a special
superpower in C++. You can use it to alias anything. It's probably from the C days where you had to play with
byte data of objects. So when optimizing the original code, the compiler has to assume,
provided there's no appropriate compiler switches, that the count can be aliased, and assigning to elements of the
string can change the count, because it can be aliased by any of the elements, because they are
pointers to char. However, using anything else to alias in C++ is undefined behavior, so the compiler
assumes it never happens. And so, since count is now a loop invariant, the whole loop can be
turned into a memset. Yeah, lots of interesting UB things that you have to be aware of.
This meeting is going to end soon.
And I will leave you with this tweet that shows a screenshot from Reddit.
Quote,
Will software engineers ever stop being in demand?
There are two schools of thought.
Those with a background in business
see developers as commodities
and fully believe that programmers
will program themselves out of a job field.
The idea is that in some distant future,
jobs like project manager, product manager
and marketing manager will still be critical,
but programmers themselves will be extinct
as a result of the tools they created.
The other school of thought is hard to understand
because the programmers are laughing so hard they can't talk.
That's it.
Thank you very much for attending this first public meeting.
Thanks and until next time.
Bye-bye.