4

Note: This question is about MSVC, not about the C++ Standard!

According to the C++ standard, calling any member function (virtual or not) on nullptr is undefined behaviour (see here and here). As such I was mildly surprised that when I created a MFC Application with the Visual Studio Wizard to find this code:

void CClassView::AdjustLayout()
{
    if (GetSafeHwnd() == nullptr)
    {
        return;
    }
    //...

Where GetSafeHwnd is defined as:

_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const
    { return this == NULL ? NULL : m_hWnd; }

This makes me wonder what the rules of MSVC actually are. According to this implementation, calling a function on a nullptr seems to be fine, it's just that this is then the nullptr. Is this assumption correct for MSVC? What if the member function is virtual? What if it's pure virtual?

Brotcrunsher
  • 1,964
  • 10
  • 32
  • 1
    @πάνταῥεῖ Please keep in mind that this is generated code from Microsoft. I guess they know what's legal with their implementation of C++ and what isn't. This is NOT a question about the C++ Standard, but a direct question about MSVC. – Brotcrunsher Aug 24 '23 at 10:35
  • 1
    I've reopened this. This doesn't ask what the standard says, only what MSVC does. – HolyBlackCat Aug 24 '23 at 10:38
  • 1
    It doesn't make much difference, they're allowed to change that at any time they'd like to, without any acknowledgement. Thus I'd never rely on that. @Brotcrunsher – πάντα ῥεῖ Aug 24 '23 at 10:38
  • @πάνταῥεῖ So what would you do in OP's position, where the generated code seems to rely on this assumption? – HolyBlackCat Aug 24 '23 at 10:39
  • @HolyBlackCat blaming the MFC devs. They're not the same people which develop the compiler. – πάντα ῥεῖ Aug 24 '23 at 10:47
  • @Brotcrunsher it's a question about MFC, not MSVC. – πάντα ῥεῖ Aug 24 '23 at 10:48
  • 3
    Asking a question of "What extended guarantees does MSVC give when..." is a question about MSVC. Closing this question is unhelpful and doesn't answer an actually practical question. – Brotcrunsher Aug 24 '23 at 10:56
  • 2
    Some of the MFC code is way older than the C++ standard. – BoP Aug 24 '23 at 13:28
  • 3
    @Peter [`GetSafeHwnd`](https://learn.microsoft.com/en-us/cpp/mfc/reference/cwnd-class#getsafehwnd) is a non-static class member of `CWnd` provided by the MFC library. You cannot change that. Plus, it is used internally by MFC literally all over the place. If compiler rules were to ever change, Microsoft would be among the first to find out. Leaving a comment or otherwise documenting the need for future re-assessment doesn't appear to be helpful. – IInspectable Aug 24 '23 at 14:18

1 Answers1

4

No, it's still not allowed.

MFC gets away with it because it's closely tied to MSVC. Microsoft ensures that the MFC code continues to work as intended with new versions of MSVC. This might include non-portable solutions.

As a practical matter, MFC doesn't use virtual inheritance or multiple inheritance in cases where this check exists. So you're on even less solid ground there.

MSalters
  • 173,980
  • 10
  • 155
  • 350