bugprone-compare-pointer-to-member-virtual-function

检测对成员虚函数指针与非空指针常量之间的相等比较产生的未定义行为。

struct A {
  void f1();
  void f2();
  virtual void f3();
  virtual void f4();

  void g1(int);
};

void fn() {
  bool r1 = (&A::f1 == &A::f2);  // ok
  bool r2 = (&A::f1 == &A::f3);  // bugprone
  bool r3 = (&A::f1 != &A::f3);  // bugprone
  bool r4 = (&A::f3 == nullptr); // ok
  bool r5 = (&A::f3 == &A::f4);  // bugprone

  void (A::*v1)() = &A::f3;
  bool r6 = (v1 == &A::f1); // bugprone
  bool r6 = (v1 == nullptr); // ok

  void (A::*v2)() = &A::f2;
  bool r7 = (v2 == &A::f1); // false positive, but potential risk if assigning other value to v2.

  void (A::*v3)(int) = &A::g1;
  bool r8 = (v3 == &A::g1); // ok, no virtual function match void(A::*)(int) signature.
}

提供对涉及成员虚函数指针或潜在成员虚函数指针的变量与任何非空指针常量的相等比较的警告。

在某些编译器中,虚函数地址不是传统的指针,而是由虚拟函数表(vtable)中的偏移量和索引组成。因此,这些指针在基类和派生类之间可能有所不同,导致直接比较时出现不可预测的行为。当处理纯虚函数指针时,这个问题尤其具有挑战性,因为它们可能甚至没有有效的地址,从而进一步复杂化了比较。

建议使用 typeid 运算符或其他适当机制来比较对象,以确保代码库中的稳健和可预测的行为。通过注意此检测并采用更可靠的比较方法,您可以缓解与未定义行为相关的潜在问题,尤其是在处理成员虚函数指针或纯虚函数指针时,从而提高代码的整体稳定性和可维护性。在涉及成员虚函数指针的情况下,建议仅使用 nullptr 进行比较。

限制

不分析存储在变量中的值。对于变量,仅分析同一 classstruct 中的所有虚方法,并在将成员虚函数指针分配给此变量时进行诊断。