162. Modules, Xmake, CMake, constexpr, operator overloading

With Gianluca Delfino, Frances Buontempo, Vladimír Arnošt, Andrew Fodiman, Paul Etheridge and other colleagues.






Powered by RedCircle

Timur Doumler’s UB survey

Timur Doumler posted on Mastodon:

Hello C++ community! In preparation for my upcoming talk @cpponsea on C++ and Safety I’m doing a little experiment: a survey on the perceived impact of undefined behaviour in C++.

If you code in C++, please help me out & participate here: Google Docs

It’s anonymous & consists of only three questions — takes only a couple mins! Results will be revealed and discussed in June at CppOnSea.


Stop Saying C/C++

<…> the problem is that when people say this term (C/C++) they make it seem like C and C++ are similar or closely related programming languages. That is not true.

Many beginner programmers are lead by the term “C/C++” to think that they’re basically the same language. In fact there are many tutorials out there that are advertised as “C/C++ tutorials”, continuing the confusion. This can also scare away C beginners by making them think that understanding the complexities of C++ are required to understand C (SPOILER: They’re not).

Hang on, Cpp2 can be combined with C++ in the same source file. Therefore I propose to rename it C++/Cpp2. Or even C++/2. Need to let Herb know, I think there’s a real gem here. (IBM might object though.)

Job descriptions asking for “x years of experience with C/C++”


In my experience, the C/C++ tag translates to: “We have a 30 year old C code-base which we made an intern rename all the files to .cpp and fix bugs until it compiled again. Our code-base is still a nightmare-scape of object-oriented patterns implemented using arrays of structs and function pointer tables. Sometimes our more knowledgeable engineers will use a std::vector. Please never template anything.”

See also: Orthodox C++

Xmake 2.7.6

Clang C++20 modules examples

It required the latest version of CMake and a lot of ceremony to set up, including some incomprehensible things like

1set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a")

C++20 modules: best practices for abstraction and encapsulation


Depends on the complexity of what you want to do.

On my repos I have both approaches.

If the module is simple enough that everything can be described in a single file, then I have everything together. Also note that for modules, writing code inside classes/struct isn’t implicit inline like it happens on header files. If however the module is relatively complex, I rather use an interface file, and then scatter the contents across several partial module implementation files.

1extern void g(int x);
3int f(int a, int b)
5  g(b ? 42 : 43);
6  return a / b;

<…> the compiler will assume that b must be non-zero because later there is a division. This is incorrect, because g may terminate the program.

Best and worst examples of operator overloading

Reddit: What’s the most hilarious use of operator overloading you’ve seen?

C# developer here. I accidentally started a nerd bender on C++ because I was pissed that I couldn’t overload the function call operator in my language of choice and now I’m marveling at some of the wild things you guys do. Bit shift writes to a stream? Awesome.

What’s the funniest, weirdest, most clever, or just plain stupidest use of operator overloading you’ve seen? In library code or in production at your own company.

Template errors are looooong

A redditor asks: Why are template errors so horrendously verbose?

Another answers:

They’re not hard to read, they’re tedious to read. The compiler is dumping the whole instantiation chain so you can find the information you need. How is it supposed to know which information you need? I’d rather have too much information than too little.

Lots of great answers in the thread.

Force Inline in C++

Megh Parikh wrote a universal force-inline macro. Redditors discussed it and explained why it’s a misleading thing to do.

ultimately, a sane compiler will optimize the code much better (on average) than you ever will hope the achieve by hand-optimization.

Inlining is not about the function call overhead, it’s about allowing more optimizations to happen at the call site

Note that the keyword inline has the sole purpose of preventing ODR violations and does not necessarily result in inlining. Not confusing at all.

Omnitrace: Application Profiling, Tracing, and Analysis

Omnitrace is a comprehensive profiling and tracing tool for parallel applications written in C, C++, Fortran, HIP, OpenCL, and Python which execute on the CPU or CPU+GPU. It is capable of gathering the performance information of functions through any combination of binary instrumentation, call-stack sampling, user-defined regions, and Python interpreter hooks. Omnitrace supports interactive visualization of comprehensive traces in the web browser in addition to high-level summary profiles with mean/min/max/stddev statistics. In addition to runtimes, Omnitrace supports the collection of system-level metrics such as the CPU frequency, GPU temperature, and GPU utilization, process-level metrics such as the memory usage, page-faults, and context-switches, and thread-level metrics such as memory usage, CPU time, and numerous hardware counters.

Note that Omnitrace, being an AMD project, only supports OpenCL and not CUDA. Take that, NVIDIA!

Regex shootout

Boost.Regex is passable, so is CTRE (I expected better, tbh). std::regex is the slowest. But Intel Hyperscan beats them all.

Eric Niebler asks about constexpr

Say I declare a constexpr object like:

constexpr int zero = 0;

Now, when I take the address of zero, I get back a const int*, not a constexpr int*. That is, constexpr isn’t part of the type system.

What is it then? Like an attribute? What mental bin do I put it in?

Ville Voutilainen responds:

You put it into a bin related to static, but not exactly similar. It’s a specifier that provides additional semantics on your variable (but not its type). That’s why it is a declaration-specifier, and not part of a type-specifier, and not part of the type system.

C++20: consteval and constexpr functions

Daniel Lemire


Ostrich algorithm

In computer science, the ostrich algorithm is a strategy of ignoring potential problems on the basis that they may be exceedingly rare. It is named after the ostrich effect which is defined as “to stick one’s head in the sand and pretend there is no problem”. It is used when it is more cost-effective to allow the problem to occur than to attempt its prevention.

In one of the projects I worked on there was a bunch of services with lots of memory leaks because memory was passed around to child processes, and if you fixed the leaks the whole system stopped working. It relied on parent process being killed by the OS and thus freeing the memory.

Another case which is sadly relevant today: missile firmware:

I was once working with a customer who was producing on-board software for a missile. In my analysis of the code, I pointed out that they had a number of problems with storage leaks. Imagine my surprise when the customer’s chief software engineer said “Of course it leaks”. He went on to point out that they had calculated the amount of memory the application would leak in the total possible flight time for the missile and then doubled that number. They added this much additional memory to the hardware to “support” the leaks. Since the missile will explode when it hits its target or at the end of its flight, the ultimate in garbage collection is performed without programmer intervention.