Category Archives: C++

How to enable colored compiler output with CMake + VSCode

Assuming you’re using the “CMake Tools” VSCode extension, here’s what works for me.

1 – Set CMAKE_COLOR_DIAGNOSTICS to ON in your environment

This makes CMake pass -fcolor-diagnostics to clang. If you build on the command line, you’ll now have color. But the VSCode “output” pane will still be non-colored.

2 – Install the “Output Colorizer” extension from IBM.

This adds color to the Output pane.

It looks like this:

Links:

https://github.com/ninja-build/ninja/issues/174

https://github.com/microsoft/vscode-cmake-tools/issues/478

Can we have non-atomic std::shared_ptr in C++?

Turns out, we do have them. libstdc++ contains a heuristic kludge where it checks if libpthread is linked into the process and conditionally executes an atomic add or non-atomic add depending on the result. Post 2020, it doesn’t directly use the libpthread hack, but uses glibc’s native support for this.

These kinds of things always make me sad about C++ (especially compared to how nice and clean things seem to be in Rust world), but at least it’s nice knowing that the committee did consider it and there are good reasons why to not have this in the C++ stdlib. The most compelling reason is that in the absence of a borrow checker, it is all too easy to silently use a non-atomic shared_ptr in multithreaded code.

Full thread:

Short thread about LLDB pretty printing internals

Tips for writing LLDB pretty printers

LLDB supports custom scripts (“variable formatters”) to pretty print C++ data structures. For example, std::vector is typically implemented as a struct with three pointers: begin, end, and capacity. But if you wanted to print out a std::vector variable during a debugging session, printing out these three pointers isn’t likely to be helpful. What you actually want is to print the contents of the vector. Pretty printer scripts allow for doing this for your own data structures.1

Here are a few tips to supplement the official documentation. Sudara also has a great post on the topic.

Continue reading

The tradeoffs in using -Weverything

In addition to the well-known -Wall, clang offers another interesting warning flag: -Weverything. While it sounds like a “strictly better” option (the more warnings, the better?) it’s not.

This topic is already well covered by Arthur O’Dwyer’s blog post and the clang documentation.

Arthur makes a strong case against use of this flag. The clang docs generally agree, though offering a slightly more lenient position:

If you do use -Weverything then we advise that you address all new compiler diagnostics as they get added to Clang, either by fixing everything they find or explicitly disabling that diagnostic with its corresponding Wno- option.

But what I have not seen clearly expressed is how use of -Weverything is a tradeoff.

Continue reading

Surgical formatting with git-clang-format

If you’re already a 10x engineer, you probably won’t need this article. But for the rest of us, this is what I wish I knew about clang-format as an inexperienced C++ programmer: how to only format the changes in your pull request.


You may have already heard of clang-format. It auto-formats source files for languages including C and C++. You can aim it at a source file and format the entire thing using clang-format -i file.cpp.

If you’re contributing to a project that is already 100% clang-format clean, then this workflow works fine. But you’ll occasionally encounter a project that is not quite 100% formatted, such as LLVM, osquery, or Electron1.

For these projects, the “format entire files” workflow doesn’t work because you’ll incidentally format parts of the files that are unrelated to your contribution. This will add noise to your diff and make it harder for your reviewers.

In this case, you need a way to surgically format only the lines changed in your contribution. To do this, you can use the clang-format git extension. This article will cover the basics of git-clang-format, including a practical workflow that allows for messy development, and formatting at the end.

Continue reading

What they don’t tell you about demand paging in school

This post details my adventures with the Linux virtual memory subsystem, and my discovery of a creative way to taunt the OOM (out of memory) killer by accumulating memory in the kernel, rather than in userspace.

Keep reading and you’ll learn:

  • Internal details of the Linux kernel’s demand paging implementation
  • How to exploit virtual memory to implement highly efficient sparse data structures
  • What page tables are and how to calculate the memory overhead incurred by them
  • A cute way to get killed by the OOM killer while appearing to consume very little memory (great for parties)

Note: Victor Michel wrote a great follow up to this post here.

Continue reading

Don’t confuse std::move and std::forward

This was a pretty interesting buggy scenario I found while reading the clang-tidy checks. If you’re writing a function that takes a forwarding reference (what looks like an rvalue reference, but whose type is a template argument), you need to be careful to not call std::move on it. You need to make sure to call std::forward instead. Otherwise, you might accidentally trigger a move on an object passed by a caller! This would be confusing, since their object would be moved from, and they never explicitly called std::move on it.

Continue reading

Getting bit by unique_ptr

I got bit by unique_ptr when implementing a linked list today. You need to be careful to manually release() the unique_ptr before resetting or you might accidentally free the entire list. This comes up when doing insertions and stuff like that.

Reproducing a GCC 8.1 ABI compatibility bug

I was reading about GCC and noticed this very suspicious warning line about an accidental compatibility break: https://gcc.gnu.org/gcc-8/changes.html

I thought it would be interesting to reproduce this. I reprodcued this specific scenario they outline and compiled two translations units, one with GCC 8.1, one with an earlier version (GCC 7) and observed the segfault that happens when two incompatible calling conventions interact with each other.