A ClangFormat Story and the Third CLion Nova Update
CLion Nova is a free preview of CLion equipped with the ReSharper C++/Rider C++ language engine. It comes with all of the newest enhancements from the CLion Classic 2023.3 release, with the exception of AI Assistant. This means you can use CLion Nova if it works best for your use case without missing out on all of the latest CLion improvements and features. CLion Nova boasts 4,000+ daily users, and the feedback continues to be positive for both IDE performance and functionality.
Today, we’re announcing the availability of a new build (233.13309). You can already update to it via the Toolbox App.
The ClangFormat story
After releasing the first build of CLion Nova, we received several complaints about incorrect formatting in the IDE. Our investigation into this issue generated some interesting findings and corresponding fixes in the product, which we believe are worth discussing in more detail.
ClangFormat is a popular formatting tool in the C++ community, though some confusion around it still persists. For example, despite being a standard tool, ClangFormat is still not widely used in C++ projects. At JetBrains, we built a tool to analyze GitHub repositories with the help of various scans configured according to our requests. We recently scanned GitHub looking for the latest project versions whose primary language is C or C++ with a rating of 10 stars or more – the search returned 163,420 such repositories. Only 14,131 (8.65%) of these included the .clang-format
file at any level.
Another popular misconception is that ClangFormat is a tool for guideline enforcements, similar to Clang-Tidy and other code analysis tools. In the recent Developer Ecosystems results for C++, ClangFormat even made it to third place in a list of such tools, with 24% of the respondents voting for it.
However, counterintuitively, ClangFormat doesn’t accurately parse C++ code in the way Clang or other compilers and IDE language engines do. To speed up the formatting of your code, it only generates annotated tokens based on a simple lexer. Thus, no accurate syntax tree is built and no #include
is accurately handled. If you’ve ever tried to format macros with ClangFormat, especially defining blocks that have to be formatted differently, you’ll know that you need to explicitly tell ClangFormat where this complex macro begins and ends via MacroBlockBegin
and MacroBlockEnd
. It’s also quite easy to confuse ClangFormat with templates:
In CLion and ReSharper, C++ users have the option of either working with the IDE’s own formatter or switching to the ClangFormat executable. ReSharper’s C++ formatter can also read the .clang-format
config file and apply the majority of the settings from it. However, because of the parsing differences between the ReSharper C++ engine and ClangFormat fuzzy parser, the results might be different!
This is where the users’ confusion came from in the first build of CLion Nova. We failed to properly migrate the setting that tells the IDE which formatter to use. Users who had ClangFormat enabled in CLion Classic thought they were using it in CLion Nova as well, but it was ReSharper C++ that read the settings from the config file and formatted the code. The widget from CLion Classic, which is ordinarily located in the bottom right corner of the editor and shows the formatter status, was also missing. This led to numerous incorrect formatting reports that we received in the first days after CLion Nova’s launch.
Now, all these issues have been addressed! You can find the formatter widget in the bottom right corner and use it to check the formatter tool used by CLion Nova on your specific project. This widget also allows you to switch to ClangFormat if you prefer it to CLionNova’s own formatter:
We’re sorry for any confusion this may have caused. Still it gave us a reason to tell you an interesting story about ClangFormat.
Other fixes
- Language fixes:
- We addressed several cases when CUDA code was incorrectly resolved (CPP-26144).
- Support for C23’s
bool
was added. - C++20
std::source_location
andstd::bit_cast
are now supported in CLion Nova. - CLion Nova now supports the following builtins:
__builtin_addressof
,__builtin_bzero
,__has_builtin
(only in preprocessor),__builtin_offsetof
, and__builtin_clzll
.
- We addressed several issues with refactorings in CLion Nova:
- We fixed the issue that prevents CLion Nova from indexing files with long paths (CPP-36597). This was critical for such cases as a docker toolchain with a cross-compiler.
- We made the Usages popup look similar to CLion Classic, where it is both cleaner and more informative:
There are also various fixes for the code analyzer, formatter, and IdeaVim plugin.
Your CLion team
JetBrains
The Drive to Develop