Transcript
Discussion (0)
My name is Gleb. I run a C++ club at work.
You can find our meeting notes at cppclub.uk.
This podcast and the meeting notes contain public information only.
This is episode 10 for the meeting number 135
that took place on the 9th of September 2021.
JetBrains, the state of developer ecosystem in 2021.
The results of the survey are available, together with the methodology they used.
More than 47,000 people participated in the survey, from 23 geographical entities.
To clean the data, they identified and threw away suspicious replies replies including those that were filled too fast
multiple surveys with overlapping results and or from the same ip address surveys with conflicting
answers like an 18 to 20 year old with a 16 years of professional experience
some interesting results the c++ standard people use is mostly c++ 11 or 17
18 already use c++ 20 which is encouraging news but then 12 are still on c++ 98 which is pretty
terrible of these 41 don't plan to migrate to a newer standard. Hello, game developers!
11% of respondents replied that they are not sure which standard they use, and I'm not sure how that
happens. Of C++20 features, 48% plan to use modules in the next year, which may be a tough cookie as only MSVC has production level support
for modules at the moment. 46% plan to use concepts and 33% plan to use coroutines. 31%
don't plan to use any C++ 20 in the next year.
The most popular C++ IDE is Visual Studio Code, 28%, followed by CLion, 26%, followed by Visual Studio, 24%.
VI is used by 6%, whereas Emacs only used by 2%.
30% don't write unit tests for C++, which is bad news. Google test is the most popular unit test
framework, followed by no framework, then catch, cpp unit, boost test, and doc test.
Third-party libraries are most often included in the project, 26%, or compiled separately, 23%.
21% of developers rely on system package managers
and 21% download binaries from the internet.
Brave.
Package managers like Conan and VCPKG
are in the single-digit percentages
and 14% are lucky to not have any dependencies.
In error reporting stats, 80% use exceptions.
In build systems CMake is the king 55% followed by Make and Visual Studio projects. In compilers
GCC wins with a whopping 78% followed by Clang 30% and MSVC 30%. MSVC C++ 20 and the std C++ 20 switch.
Microsoft announced that the new version of Visual Studio 2019 version 16.11
has a new compiler switch std C++ 20. Quote the addition of this switch indicates that we've reached a point of sufficient
stabilization of the msvc c++20 feature set for it to be used in production with full support
in the vs servicing updates if you think it means that the new switch allows you to use
all the standard c++ features you're in for a couple of small surprises.
The new switch signifies a stable ABI. The experimental switch is still std C++ latest.
Both imply permissive minus for strict standard compliance. You can turn this off, but then some
C++ 20 features won't be available like modules.
Let's see what those surprises are. C++ defect reports were raised during
implementation of C++ 20 due to some late discoveries. Fixes for those issues
will be available under std c++ latest and then eventually under std c++ 20. this includes things like std format
improvements superior string splitting and other fixes and clarifications there is uncertainty in
how to implement allowing virtual function calls in constant expressions. The way it is implemented has ABI implications and
so Microsoft implemented two additional switches experimental constvalvfunc
vtable and experimental constvalvfunc novtable. Once they decide which way is
the best it will be made available under both std c++ latest and std c++20.
Coroutines have been supported in MSVC since C++14. What? Given the fact that
C++20 is the first official standard to support them, it becomes a bit awkward. So there is now a new switch. A wait strict which removes
coroutine features not available in C++20. Luckily it is implied by std C++20. And now we come to the
most interesting surprise of them all. The new C++20 attribute, no unique address, breaks ABI by changing class layout, combined with the fact that MSVC ignores
unknown attributes, this results in ABI incompatibility between the same code built in C++17
and C++20 modes, and also when linking with libraries built using older tool sets in the
supposedly binary compatible range. So Microsoft decided to just not implement
this attribute to keep backward binary compatibility until the next ABI breaking release
whenever that happens. As you may remember it won't happen in the next version of Visual Studio yet
as Visual Studio 2022 and MSVC 143 keep binary compatibility. For those lucky developers who don't care
about older versions of MSVC, there is now a Microsoft-specific attribute
MSVC colon colon no unique address, which enables the optimization in all language modes C++14
to C++20. They advise to use a macro that guards this attribute with an MSVC
version check. More macros, yay! There is a thread on Reddit with some interesting replies
from Stefan T. Laubowade himself. Safer usage of C++. Google released a long document describing their internal C++ safe programming techniques
as applicable to Chromium. Quote, Chrome security has been asked to consider what it would take
to make C++ less dangerous. This document outlines various mechanisms we could use to make it
significantly easier to use C++ safely. Some are radical and adopting them,
especially adopting many of them, may result in code that looks quite different from what C++
programmers expect. Most of the proposed mechanisms are new usage patterns, libraries, and classes,
but some call for the use of compiler-specific flags that change the language somewhat.
For example, Chromium already uses Fnoexceptions.
Some of these mechanisms are already being built in Chromium, with varying degrees of
success.
Other mechanisms we propose represent significant new directions for C++ and Chromium. The C++
language and culture tend to trade off safety in favor of efficiency. And therefore, many of these
proposed changes are complex, controversial, and not as robust as similar changes might be in
another language. They define a couple of terms. Spatial safety is the guarantee that the program will behave
in a defined and safe way if it accesses memory outside valid bounds. Examples include array
bounds, struct and union field access, and iterator access. Temporal safety is the guarantee that the
program will behave in a defined and safe way
if it accesses memory when that memory is not valid at the time of the access.
Examples include useAfterFree, which is responsible for 48% of security bugs,
doubleFree, useBeforeInitialization and useAfterMove.
The document names undefined behavior as the source of many problems in C++.
The authors propose a number of measures to make C++ programming safer in Chromium.
Remove or reduce raw pointers.
Ban the direct use of raw pointers new and delete. MiraclePeta aims to make a smart pointer type
that eliminates use after free while not impacting the performance too much. Oilpan is the blink
render engine's garbage collector which can be now generally used in Chromium codebase. Annotate lifetimes using Clang's ClangLifetimeBound attribute,
but this has too many limitations and increases visual noise in the code.
Implement automatic memory management like reference counting,
C, Objective-C and Swift, or full garbage collection.
Implement ownership analysis. Enforce at runtime that there is a
single owner of any object which can only be changed via std move like borrows in rust.
This solution is a poor fit for C++. Use the warning dangling GSL. Google has had good results with this switch.
Define all standard library behaviors where possible by adding a compile switch for hardened mode, like in upsell.
Define undefined iterator behaviors by using a checked iterator facility.
Define integer semantics by using a wrap-on numerics library, using a compiler option to make signed integer overflow defined, wrap-around, using undefined behavior sanitizer.
But there is a problem. Assuming overflow behavior is a significant change semantics, and if developers come to rely on the newly defined behavior, a compiler switch change would make all that code defective.
Set pointers to null after free.
Peter Somerlad pointed out on Twitter that these would likely be optimized out.
And define null pointer dereferences.
Clang has the switch fnodeleat null pointer checks, which results in not optimizing out
null pointer dereferences and crashing instead of continuing.
Require coding patterns to reduce lifetime errors.
Use variant instead of enums.
Or Google's upsell variant.
Ban studunique pointer get.
Use shared pointers. This is the opposite of the current guideline to
prefer std unique pointer to std shared pointer. I don't see it that way. If you need to share,
use a shared pointer and not the raw pointer extracted from a unique pointer.
Initialize all memory. Can be expensive at runtime. Remove primitive arrays.
Remove mutable shared state.
One of the solutions is a borrow checker in the compiler like the one in Rust.
Check type costs.
Type confusion accounts for 7% of Chromium high severity security bugs.
Prevent use after move using a Clang plugin.
Use memory tagging. Depending on the specific mechanism pointers to and or regions of memory are tagged and if code tries to load or store
memory without using the right tag the program faults. Control flow integrity enforcement Intel Flow Integrity Enforcement, Intel CET technology is enabled on Windows and Apple ARM-based systems.
Reddit says, quote,
Wow, it sounds like if Google is considering moving to C++11.
For the rest, it reads like a total disaster, with a major C++ player apparently intending to entirely go their own way,
forking a compiler and the entire language, and doing
their own thing from here on out.
And another one, quote, it kinda looks like they're trying to mimic Rust's safety with
compiler extensions and static analysis to C++.
And then, from what I hear, the preferred solution would have been to rewrite Chromium in Rust,
but it required too much engineering efforts, so this is the alternative.
End quote.
I vividly remember the kind of alien code we used to write back at Symbian
to prevent various memory problems and bugs.
A large part of every function was memory management.
It was an entire custom dialect
of C++ and Google seems to be going in the same direction. Good luck with that.
DIY's Sanitize This article by Myrin Peco is an introduction
to sanitizers. Address sanitizer,-Sun, and Undefined Behavior Sanitizer, Ubi-Sun. Unfortunately,
it omits Thread Sanitizer, T-Sun. Still a useful summary of what the sanitizers do and how they
work, with a shout out to Valgrind, which is much slower than any of these. By the way, regarding
false positives, A-Sun doesn't produce any. Errors it finds are actual bugs.
msun can produce them if you don't rebuild all your libraries with msun.
And ubisun can sometimes produce false positives.
Reddit thread has some useful comments, including this tip
on how to prevent asun from aborting the program on the first error.
In addition to the usual switch fsanitize address use
fsanitize-recover equals address and then at runtime set the following environment variable
asan underscore options equal hold on error equals zero. If you're not using sanitizers
in your C++ projects yet you really should start. That's it for today
I leave you with this quote by Meir Lehman. An evolving system increases its complexity
unless work is done to reduce it. That's it take care bye