Developing C/C++ is fun!


C/C++ isn’t my usual go-to for work or play. My initial encounters with it were, let’s say, a bit prickly. There were definition not found errors all over the place, and the code completion was not as smart as modern languages.

Recently I was exploring some awesome projects written in C/C++ (say DuckDB). After some research to configure the development environment, I discovered that with the help of powerful language tools, developing C/C++ can be as enjoyable as working with other modern languages.

In this post, I’m going to share my journey of setting up a C/C++ development environment. I hope it could be helpful for you.

Use LSP-compatible code editor

I currently use Zed as my editor. It’s sleek, it’s speedy, and it’s pretty cool. Internally, it uses clangd as the language server. Thanks to LSP, all code editors today can provide consistent features (e.g. code completion, go-to-definition, and refactoring) powered by Clang toolchain. Thus the following steps should be also applicable to code editors that support LSP.

Configure clangd

clangd provides a rich set of features out of the box. However, unlike modern languages, say Golang or Rust, C/C++ projects have no standard structure. This flexible structure can make it difficult for the language server to understand the project without proper configuration. In particular, clangd uses compilation database to understand the source code. It’s a JSON file providing compile commands for every source file in a project, and is usually generated by tools. clangd manual describes how to generate this file for Cmake and Bazel projects.

Generate configuration using Bear

But, not all projects (like Postgres) use these build systems. In this case, Bear can generate it by recording a complete build. To generate the compile_commands.json file, install Bear and run bear -- make. Then clangd can understand the project and provide features like code completion and refactoring.

Conclusion

So, ready to dive into C/C++ development? Here’s what you need to do:

  1. Use a code editor that supports LSP (e.g. Zed, VSCode, or Vim).
  2. Choose clangd as the language server and provide it with a compile_commands.json file.
  3. For Cmake/Bazel projects, use their built-in tools to generate that file. For other projects, use Bear.