禁用联合体
5.3.3 ID_forbidUnion
联合体的问题主要有:
- 无法只通过对象获取当前有效的成员
- 访问不同的成员相当于不安全的类型转换
- 对非基本类型的成员造成构造和析构的混乱
- 不能作为基类
这些问题在本质上是对类型理念的破坏,面向对象的程序设计应避免使用联合体。
示例:
union U { // Non-compliant
int i;
char c;
};
U u;
u.i = 1000;
cout << u.c << '\n'; // Equivalent to a cast without any restrictions
例中对 u.c 的访问也相当于一种没有任何限制的类型转换。
在 C++ 代码中建议用 std::variant 或 std::any 取代联合体:
std::variant<int, char> u;
u = 1000;
cout << get<int>(u) << '\n'; // OK
cout << get<char>(u) << '\n'; // Throw ‘std::bad_variant_access’
std::variant 可以有效记录对象当前持有的类型,如果以不正确的类型访问对象会及时抛出异常。
本规则比 ID_forbidNakedUnion 更严格,针对所有联合体。
相关
参考
MISRA C 2004 18.4
MISRA C 2012 19.2
MISRA C++ 2008 9-5-1