This is a draft version of a MISRA C++ 202x rule proposed for public review.
MISRA Rule 13.3.4
Category: Required
Analysis Type: Decidable,Single Translation Unit
Amplification
A pointer to member function is potentially virtual if it is:
- A compile-time constant that points to a virtual member function; or
- A pointer to member function of a class that is incomplete at the end of the translation unit; or
- Not a compile-time constant pointer to member function and has a type matching that of a virtual member function of its class.
Rationale
The result of comparing a pointer to member function that points to a virtual function with anything other than nullptr
is
unspecified.
Example
class A
{
public:
void f1();
void f2();
virtual void f3();
};
void foo()
{
if ( &A::f1 != &A::f2 ) {} // Compliant
if ( &A::f1 != nullptr ) {} // Compliant
if ( &A::f3 == &A::f2 ) {} // Non-compliant - f3 virtual
if ( &A::f3 == nullptr ) {} // Compliant
}
void bar( void ( A::*ptr )() )
{
if ( ptr == &A::f2 ) {} // Non-compliant - ptr potentially points to A::f3,
// which is virtual
}
Note: the example above would be compliant if A
had no virtual members.
class B
{
public:
void f1();
void f2();
virtual void f3( int32_t i );
};
void bar( void ( B::*ptr )() )
{
if ( ptr == &B::f2 ) {} // Compliant - there are no virtual functions
// in B with the appropriate signature
}
class D: public A // Inherits virtual functions from A
{
public:
void f4();
};
void car( void ( D::*ptr )() )
{
if ( ptr == &D::f4 ) {} // Non-compliant - ptr potentially points to A::f3,
// which is virtual
}
struct E;
void foo ( void ( E::*p1 )(), void ( E::*p2 )() )
{
if ( p1 == p2 ) {} // Non-compliant - 'E' is incomplete, so it is
// unknown if the pointers are to virtual members
}
// The following definition of E anywhere in the translation
// unit would make the above example compliant
// struct E{ void f1(); void f2(); };
Copyright The MISRA Consortium Limited © 2023