☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

不应转换无继承关系的指针或引用

12.9 ID_castNoInheritance
目录 › next › previous

无继承关系的指针或引用之间没有逻辑关系,转换意味着设计缺陷或逻辑错误。

示例:

float f = 0;
int* p = (int*)&f;  // Non-compliant
(*p)++;             // Undefined behavior

基本类型之间没有继承关系,float* 转为 int* 属于逻辑错误,导致标准未定义的行为。

有时为了考察对象内部结构,需要将对象指针转为 unsigned char* 等类型,但这种转换脱离了类型的保护,也会降低代码的可移植性,审计工具不妨通过配置决定是否放过这种转换。

又如:

class A { .... };
class B { .... };
class C: public A, public B { .... };

A* a = new C;

B* b0 = (B*)a;                    // Non-compliant
B* b1 = reinterpret_cast<B*>(a);  // Non-compliant

B* b2 = static_cast<B*>(a);       // Compliant, compile-time protected
B* b3 = dynamic_cast<B*>(a);      // Compliant, run-time protected

例中 A 与 B 没有继承关系,C 从 A 和 B 继承,指针 a 为 A 类型但实际指向 C 的实例,这种情况下将 a 直接强制转为 B 类型的指针将得到错误的结果,这种问题在实际代码中也很常见。

本规则限制无继承关系的 C 风格类型转换以及 reinterpret_cast 转换,不限制 static_cast 和 dynamic_cast 转换,示例中的 static_cast 转换将得到编译错误从而锁定问题,如果 A 和 B 是多态类型,用 dynamic_cast 会得到正确的结果。

例外:

class V { .... };

class U {
    ....
public:
    operator V*();   // Conversion operator
};

U* u = new U;

V* v0 = (V*)u;                     // Compliant, but bad
V* v1 = reinterpret_cast<V*>(u);   // Still non-compliant

例中 U 和 V 是无继承关系的类,但 U 实现了向 V 的转换运算符,U 和 V 之间存在逻辑关系,这时的 C 风格类型转换可不受本规则限制,但不符合规则 ID_forbidCStyleCast,这种情况仍然不能使用 reinterpret_cast,参见 ID_unsuitableReinterpretCast。

配置

allowWeakerCast: 是否放过与 unsigned char* 的转换

相关

ID_stricterAlignedCast ID_castNonPublicInheritance

依据

ISO/IEC 9899:1999 6.5(7)-undefined ISO/IEC 9899:2011 6.5(7)-undefined ISO/IEC 14882:2003 3.10(15)-undefined ISO/IEC 14882:2003 4.1(1)-undefined ISO/IEC 14882:2011 3.10(10)-undefined ISO/IEC 14882:2011 4.1(1)-undefined

参考

MISRA C 2012 11.3 MISRA C++ 2008 5-2-7 SEI CERT EXP39-C
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.