Blog post

Sonar ❤️ Compiler Explorer: Write clean C++ code inside your browser

Fred Tingaud photo

Fred Tingaud

Developer

5 min read

  • C++

We are happy to announce that it is now possible to run Sonar static analysis inside Compiler Explorer!

Not only is your code compiled as you write it, but it can now also be linted. You just have to select Sonar in the tools list and you will get issue highlighting inside the editor, a description of what is wrong and how to fix it, automatic fixes where applicable, and more!

Compiler Explorer

In the C++ community, Compiler Explorer has become an essential tool thanks to its ubiquity and convenience.

If you haven't had the chance to hear about Compiler Explorer yet, imagine an online IDE where, as you type, your code is compiled, executed, and the generated assembly code is displayed. Or don't imagine and visit https://compiler-explorer.com/.

If you add to that multiple integrated tools to inspect the code and the possibility of sharing URLs, you have one of the best tools for prototyping, demoing, sharing code snippets, validating hypotheses, and much more.

Because Compiler Explorer is the perfect tool for sharing code, all the examples we mention in this post come with fully configured links in Compiler Explorer.

Sonar tooling

At Sonar, we provide static analysis tools that detect bugs and code smells without asking you to manually instrument or change your code. 

We believe that the continuous use of these tools leads to Clean Code.

SonarLint, a static analysis solution in your IDE, is the tool that most resembles what was introduced in Compiler Explorer. We also provide SonarQube and SonarCloud to work as part of your continuous integration/deployment pipeline and to enable our Clean as You Code approach.

Sonar analysis in Compiler Explorer

To use the Sonar analysis integration with Compiler Explorer, make sure you have selected either C or C++ as your language and a GCC or Clang compiler.

You will find a menu "Add tool..." in the compiler output window, with a "Sonar" entry. Select it, et voilà! https://compiler-explorer.com/z/jaGfW76YY

A screenshot of the "Add tool..." menu with Sonar plugin highlighted

Detected issues are highlighted with a golden squiggle in the code, and details are available in the Sonar window or when hovering over the highlighted code.

A general screenshot of Compiler Explorer with the Sonar integration activated

Some use cases

Will this new tool improve your life? Here are a few situations where we think Sonar analysis will make your life better.

Play with a new C++ feature

We strive to cover new language features as soon as possible after they are supported and stable in the major compilers. We know that Compiler Explorer will often be where you will first experiment with language features before they reach your production code. That's where we want to be: we aim to educate the public on how to use these features correctly.

Imagine you work for a company that uses C++17 in production. You read about C++20 bringing concepts and you want to try them to better grasp how they would benefit your job. You fire up Compiler Explorer and start writing a pet example to understand, hands-on, what is going on.

Your first attempt at differentiating integers from strings compiles but when you test it with static_asserts, you realize it doesn't do what you expected at all:

#include <concepts>
#include <string>

template<typename T>
concept IsNumericID = requires () {
   std::is_integral_v<T>;
};

template<typename T>
concept IsTextualID = requires() {
    std::is_same_v<T, std::string>;
};

static_assert(IsNumericID<int>);
static_assert(!IsNumericID<std::string>);
static_assert(!IsTextualID<int>);
static_assert(IsTextualID<std::string>);
C++ Code - Failing concept use

You add the Sonar analysis to your code and see that you have issues raised on both concept declarations:

One Sonar issue: "Requires-expression should not contain unevaluated concept checks or type predicates. (cpp:S6456)" and a link to the full description at https://rules.sonarsource.com/cpp/RSPEC-6456

https://compiler-explorer.com/z/8T1Tzxr6G

Because you don't know the subject well, the issue description does not really enlighten you, but luckily, this description also contains a link to a more in-depth explanation of the subject! You click on the link to https://rules.sonarsource.com/cpp/RSPEC-6456 where you learn about simple requirements, why your type traits are not evaluated in this context, and how to correctly write your checks. A few minutes later, your pet project is both simpler and working as expected https://compiler-explorer.com/z/97Tx8vaqr.

Writing a presentation

Now imagine you are preparing a talk for your peers about image quality and color spaces. A subject you're an expert in. Of course, you always use Compiler Explorer to prepare all the code snippets you'll present. It allows you to make sure everything compiles correctly and also to quickly open a snippet and modify it interactively if anybody asks a question.

One of your slides reads as follows:

#include <array>

enum class ColorSpaces { rgb, hsv, hsl, lab, xyz };

std::array<float, 3> getRed(ColorSpaces space) {
  switch (space) {

    case ColorSpaces::rgb: return { 1.0f,  0.0f,  0.0f};
    case ColorSpaces::hsv: return { 0.0f,  1.0f,  1.0f};
    case ColorSpaces::hsl: return { 0.0f,  1.0f,  0.5f};
    case ColorSpaces::lab: return {53.2f, 80.1f, 67.2f};
    case ColorSpaces::xyz: return {0.41f, 0.21f, 0.02f};
  }
  return { 0.f,0.f,0.f };
}
Code of the slide

When you activate Sonar analysis with C++20, you get the following issue:

A Sonar issue: Reduce verbosity with "using enum" for "ColorSpaces". (cpp:S6177)
	↳ 💡 A Quick Fix is available for this issue
	↳ https://rules.sonarsource.com/cpp/RSPEC-6177

https://www.compiler-explorer.com/z/b6qG7sWhM

Reducing verbosity in a presentation slide is extremely valuable, so you click on the issue description and your cursor switches to the corresponding position in the editor. A blue lightbulb icon appears near the cursor that you can click to automatically fix the code.

Screenshot of the quick fix menu

Your code is now less verbose and more straightforward for the attendees of your talk. They will be able to concentrate on the real point of the slide. https://compiler-explorer.com/z/hc5a773Tr

What's wrong with this code?

A common use case for Compiler Explorer is sharing a code snippet that behaves in a different way than expected. If our tooling can find bugs at this level, we save time for the person sending the snippet and all the recipients. This time can instead be spent more constructively sharing this knowledge or discussing best practices to avoid the issue.

Imagine you're working on a UI system and you're struggling with your latest component that appears at the wrong depth although the z-order is correctly passed. You manage to reproduce the problem in Compiler Explorer and intend to send it to a few experts you know, who could explain what is going on.

#include <iostream>

struct Widget {
  explicit Widget(int zorder) {
    std::cout << "Widget(zorder = " << zorder << ")" << std::endl;
  }
};

struct InputController {
  int zorder;
};

class InputField : public Widget, public InputController {
public:
  int x;
  int y;

  explicit InputField(int z) : InputController{z}, Widget{zorder}, y(z), x(y + 1) {}
};
Code of a new InputField

Before you send it, though, you check what Sonar analysis has to say about this snippet and discover multiple issues on the InputField initialization.

Sonar issues: 18:32  ➕ Reorder initializers to match the runtime order. (cpp:S3229)
	↳ 💡 A Quick Fix is available for this issue
	↳  1 Base struct Widget is initialized at this point, struct InputController is initialized after.
	↳  2 Base struct InputController is initialized at this point, struct Widget is initialized before.
	↳  3 Field "x" is initialized at this point, "y" is initialized after.
	↳  4 Field "y" is initialized at this point, "x" is initialized before.
	↳ https://rules.sonarsource.com/cpp/RSPEC-3229
18:59  base class 'InputController' is uninitialized when used here to access 'InputController::zorder' (cpp:S836)
	↳ https://rules.sonarsource.com/cpp/RSPEC-836
18:76  field 'y' is uninitialized when used here (cpp:S836)
	↳ https://rules.sonarsource.com/cpp/RSPEC-836

https://www.compiler-explorer.com/z/G5Y35K9v6

When clicking on the first issue text “18:32  ➕ Reorder initializers to match the runtime order. (cpp:S3229)” you see indicators in the code pinpointing each of the 4 ordering issues you have.

Screenshot of the indications inlined in the code. Each initialization of the constructor is prefixed with an index that corresponds to the issues showed previously.

With all these indications, you now realize that the problem comes from the order of initialization of the subclasses and can rethink the architecture of this component to avoid it.

And others

These are just a few examples, but many other situations will benefit from this integration. Finding errors as quickly as possible during live coding sessions, testing Sonar tooling without installing anything on your machine, you name it!

You can post on our Community hub or reach out to us on social networks (Twitter, Mastodon, LinkedIn) if you want to give us feedback or tell us how this feature has helped you!

It's just the beginning!

For technical reasons, the integrated analysis only covers a subset of all our rules. We think it covers enough to give a good idea of the benefits our static analysis can provide. Still, a SonarQube or SonarCloud analysis might find more issues than what appears in Compiler Explorer.

Also, at the moment, the analysis in Compiler Explorer is limited to GCC and Clang, and to the C and C++ languages, while our official tools support a much wider range of compilers and languages. Therefore, we encourage you to go discover our other tools at Sonar Open Source Solution and try them too!

Free Video! Learn what tools can help your C++ code stay clean.
Watch Now