C++:S2107, S3230 false negative

*c++

  • S2107, S3230
  • Does not detect Uninitialized C++ Member Variables
  • SonarQube Server 10.7
// CMFCApplication1Dlg dialog
class CMFCApplication1Dlg : public CDialogEx
{
// Construction
public:
	CMFCApplication1Dlg(CWnd* pParent = NULL);	// standard constructor

// Dialog Data
	enum { IDD = IDD_MFCAPPLICATION1_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support


// Implementation
protected:
	HICON m_hIcon;

	// Generated message map functions
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
	int m_nDummy;
};

// CMFCApplication1Dlg dialog



CMFCApplication1Dlg::CMFCApplication1Dlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CMFCApplication1Dlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

Although the member variable int m_nDummy; is declared without initialization, SonarQube does not report any issue, even though rules such as S2107 are enabled.

and it seems the issue mentioned there hasn’t been resolved yet.
Could you please confirm if our case is related to this known issue?

Hi @viva
Thank you for reaching out for confirmation.
I didn’t investigate, but at first glance, what you linked is still relevant, so CPP-4175 should cover the case. There was no work related to that rule since then. So, it still deserves attention on our end. Reports like yours, help us prioritize such work.
Thank you.

This issue (CPP-4175) was created back in 2023 and still appears to be unresolved.
Is there currently any plan or ETA for resolving it?
Alternatively, is there any known workaround or recommended approach we could take in the meantime?

We have many ambitious ideas in the pipeline. Thus, I can’t commit to predictions and ETAs. What I can share is that I’ll raise this, and we will reconsider prioritizing it.

I can imagine that my reply wasn’t satisfying. Unfortunately, the implementation needs an overhaul, thus I can only repeat my suggestion from the linked ticket:

I hope in the future we will have the bandwidth to tackle CPP-4175.

But S3230 is also not detected in analysis.
If this rule isn’t triggering either, what would be the recommended next steps?
Is there any workaround or configuration adjustment we should consider?

In your case, I’d need to know what the DECLARE_MESSAGE_MAP() macro expands to.
I suspect that it expands to some user-defined type (not a standard container or anything below the std namespace); and it has an opaque constructor.
That constructor will be invoked form the CMFCApplication1Dlg::CMFCApplication1Dlg constructor. Since we don’t know what it does, it may reinterpret_cast the this pointer and initialize the encapsulating object’s m_nDummy field; thus we try to avoid false-positive reports, and so we conservatively assume that initialization must have happened. This phenomenon is tracked under CPP-5871.

This may sound counterintuitive, but it is technically correct. I’d agree with you that the tradeoffs are probably questionable at best.

We had a similar case in CPP-5269, where even standard containers triggered this conservative behavior, causing many false-negative reports. That was fixed in SonarQube Server 10.7.


Unfortunately, I don’t have anything to suggest for you to improve the detection of the rule S2107 or S3230. The presence of the constructor bodies would usually help, but it’s not something I could recommend universally as good practice.

My intention with my previous suggestion was to use good judgment and strive to use in-class initializers where possible.