C++ duplication detection

Environment:

  • Product: SonarQube Server
  • Version: 2025.4.4.119049
  • Language: C++
  • Analysis type: Pull request analysis
  • Metric: new_duplicated_lines_density

Problem description:
SonarQube reports duplicated lines between two implementations of a
C++ interface class

The duplicated sections consist of interface/implementation boilerplate and
Doxygen documentation references. We already use \copydoc in the
implementation in order to avoid duplicating the documentation text. From a
C++ design perspective, the repeated declarations and override methods are
required by the interface/implementation relationship and cannot be factored
out without changing the API or reducing readability.

The duplication is therefore not accidental copy-paste. It is caused by a
common and unavoidable C++ pattern: an interface declares the virtual methods,
while the implementation has to repeat the corresponding method declarations
and definitions.

Expected behavior:
The duplication detector should avoid reporting or significantly reduce
duplication for unavoidable C++ interface/implementation constructs, especially
when the implementation uses Doxygen \copydoc instead of repeating the full
documentation.

Alternatively, SonarQube should provide a documented way to exclude such
constructs from duplication detection without excluding the complete files.

Actual behavior:
The pull request receives duplicated-code findings or an increased
new_duplicated_lines_density value for these interface/implementation
constructs.

Impact:
This produces a misleading duplication result and can fail the quality gate,
although the code follows a standard C++ design pattern and the documentation
has already been deduplicated using \copydoc.

Reproducer:
The following reduced pattern reproduces the situation:

class IExample
{
public:
    virtual ~IExample() = default;

    //! Performs the operation.
	//!
    virtual void perform() = 0;
};

class ExampleA final : public IExample
{
public:
    ~ExampleA() override = default;

    //! \copydoc IExample::perform()
	//!
    void perform() override;
};

class ExampleB final : public IExample
{
public:
    ~ExampleB() override = default;

	// THE FOLLOWING COMMENT IS MARKED AS DUPLICATION	
    //! \copydoc IExample::perform()
	//!
    void perform() override;
};

Hi @KUGA2, let’s keep it to one problem per post. Can I suggest we investigate the C++ duplication detection here. and that you create another post giving us some more details about the PR decoration problem for duplicated code?

I’m flagging this for the team responsible for duplication detection so that they can consider whether it makes sense to detect this code as duplicate or not. Thanks for reporting!

If you insist.. :(. This is now only about the SECOND issue. Edited OP.
Looking forward to a solution.

Hi @KUGA2,

I agree with you that ideally, this code should not be marked as duplicated. Unfortunately, the algorithm we use to detect duplicated code works at low level and has no notion of classes and override.

I can’t think of a clean way to solve this issue. I created a ticket to track this and see if we can think of a clever trick that could work.

I do not think that is correct. It does know of overrides (and their necessity to repeat code). If it would not have any special handling for that, it would also mark the C++ code as duplicate. But it only marks the comments! I repeat: The code is not marked as duplication (good), only the comment!

I can :D. Treat all lines with doxygen copydoc (or similar) as no duplication.

That sounds strange… Comments are supposedly fully ignored by the algorithm… Can you share a screenshot and a reproducer file?

You were right. Duplication appears on all lines.

This is how it looks like in PR:

In my reproduction, i only added those comments. The duplicate code itself already there.

I can see that in main branch:

Updated suggestion Ignore lines (or blocks) with:

  1. override;
  2. final;
  3. \copydoc