visual-c++mfccode-inspection

C26434 Function xxx hides a non-virtual function


Take this simple code:

void CRestoreSettingsDlg::OnSize(UINT nType, int cx, int cy)
{
    CResizingDialog::OnSize(nType, cx, cy);

    m_gridBackupLog.ExpandLastColumn();
}

Why is it being flagged?

enter image description here

C26434 Function 'CRestoreSettingsDlg::OnSize' hides a non-virtual function 'CRestoreDialogDlg::OnSize'.

As you can see, I call the base class method.


Declarations and Definitions


public:
    afx_msg void OnSize(UINT nType, int cx, int cy);

void CRestoreSettingsDlg::OnSize(UINT nType, int cx, int cy)
{
    CResizingDialog::OnSize(nType, cx, cy);

    m_gridBackupLog.ExpandLastColumn();
}

public:
    afx_msg void OnSize(UINT nType, int cx, int cy);

void CResizingDialog::OnSize(UINT nType, int cx, int cy)
{
    CDialogEx::OnSize(nType, cx, cy);

    Invalidate(TRUE);
}
protected:
    afx_msg void OnSize(UINT nType, int cx, int cy);

_AFXWIN_INLINE void CWnd::OnSize(UINT, int, int)
    { Default(); }

Inheritance

  1. class CRestoreSettingsDlg : public CResizingDialog
  2. class CResizingDialog : public CDialogEx

Solution

  • C26434 warning documentation links to C.128 C++ Core Guidelines Rule. It explains that to enforce correct usage of virtual functions, non-virtual function hiding should produce a warning.

    However, with MFC message maps, you have to name your message handler as specified in macro, OnSize in this case, and, since message handlers already dispatched by a virtual function (that is hidden in *_MESSAGE_MAP() macros), message handler by themselves don't have to be virtual.

    So it may be seen as a false alarm. Or maybe seen as violation of the above mentioned C.128 rule by MFC itself. No surprise - MFC is decades older than these guidelines.

    So I guess you can go ahead and suppress it for all afx_msg functions. Maybe redefine afx_msg to include __pragma(warning(suppress(...))), or just have suppression around afx_msg block.


    Some options for suppression (Godbolt's compiler explorer demo):

    
    #define afx_msg // this is normally defined by MFC
    
    struct base
    {
        afx_msg void OnSize(){}
    };
    
    
    struct derived1 : base
    {
        afx_msg void OnSize() {} // produces C26434
    };
    
    // Suppression by adding some code:
    
    struct derived2 : base
    {
    #pragma warning(push)
    #pragma warning(disable:26434)
        afx_msg void OnSize() {} 
    #pragma warning(pop)
    };
    
    struct derived3 : base
    {
        [[gsl::suppress(c.128)]] afx_msg void OnSize() {}
    };
    
    
    // Suppression by redefining MFC macro -- dirty but less intrusive:
    
    #undef afx_msg
    #define afx_msg __pragma(warning(suppress:26434))
    
    
    struct derived4 : base
    {
        afx_msg void OnSize() {} 
    };
    
    
    #undef afx_msg
    #define afx_msg [[gsl::suppress(c.128)]]
    
    
    struct derived5 : base
    {
        afx_msg void OnSize() {}
    };