枚举类
来源:互联网 发布:网络新词及解释 编辑:程序博客网 时间:2024/06/01 10:18
静态代码分析工具可简化编码过程,检测出错误并帮助修复。PVS-Studio 是一个用于 C/C++ 的静态代码分析工具。该团队检测了 200 多个 C/C++ 开源项目,包括了 Unreal Engine、Php、Haiku、Qt 和 Linux 内核等知名项目。于是他们每天分享一个错误案例,并给出相应建议。伯乐在线翻译组正在翻译这个系列,今天是第一篇。
下面这个 Bug 是在 Source SDK 的源代码中发现的。
错误代码:
这种错误的例子代码量都非常大,我尽可能地选取其中最小的一部分,但是很抱歉,代码看起来依旧很冗长。
enum
PhysGunPickup_t
{
PICKED_UP_BY_CANNON,
PUNTED_BY_CANNON,
PICKED_UP_BY_PLAYER,
};
enum
PhysGunDrop_t
{
DROPPED_BY_PLAYER,
THROWN_BY_PLAYER,
DROPPED_BY_CANNON,
LAUNCHED_BY_CANNON,
};
void
CBreakableProp::OnPhysGunDrop(...., PhysGunDrop_t Reason)
{
....
if
( Reason == PUNTED_BY_CANNON )
{
PlayPuntSound();
}
....
}
解释:
Reason 变量是属于枚举类型 PhysGunDrop_t,却用它和属于另一个枚举类型的常量作比较,这种比较显然是个逻辑错误。
但是这种 bug 模式很普遍,我甚至在像 Clang、TortoiseGit 和 Linux Kernel 这种项目中都有碰到过。
为什么会如此频繁?因为在标准C++中,枚举类型本来就不是类型安全的。到底什么该跟什么做比较,很容易让人混淆。
正确代码:
我不太确定这段代码的正确版本应该是什么样的,我猜想 PUNTED_BY_CANNON 应该用 DROPPED_BY_CANNON 或者 LAUNCHED_BY_CANNON 来替代。此处就用 LAUNCHED_BY_CANNON 来代替了。
if
( Reason == LAUNCHED_BY_CANNON )
{
PlayPuntSound();
}
建议:
我想告诉大家的是一些新的特性都有它的好坏两面性。 但是对于“枚举类”, 我坚信使用它有百利而无一害。枚举类也是c++11的新引入的特性。在使用枚举类的时候,必须明确指出指定的常量属于哪个枚举类型,以免在代码中出现错误。使用枚举类更新后的代码如下:
enum
class
PhysGunDrop_t
{
DROPPED_BY_PLAYER,
THROWN_BY_PLAYER,
DROPPED_BY_CANNON,
LAUNCHED_BY_CANNON,
};
void
CBreakableProp::OnPhysGunDrop(...., PhysGunDrop_t Reason)
{
....
if
( Reason ==PhysGunDrop_t::LAUNCHED_BY_CANNON )
{
PlayPuntSound();
}
....
}
说真的,修复旧代码的确会有一定困难,但我强烈推荐你们现在就开始在代码中使用枚举类,你的项目定会从中受益。
我觉得在这儿详细介绍枚举类没有多大意义,下面的一些链接可供大家参考学习,从中你会了解到关于C++11这个出色的新特性的所有细节。
- Wikipedia. C++11. Strongly typed enumerations.
- Cppreference. Enumeration declaration.
- StackOverflow. Why is enum class preferred over plain enum?
这个错误是用静态代码分析工具 PVS-Studio 检测到的,错误信息为:V556 对不同枚举类型的值进行比较:Reason == PUNTED_BY_CANNON。
- 枚举和枚举类
- 枚举类
- 枚举类
- 枚举类
- 枚举类
- 枚举类
- 枚举类
- 枚举类
- 枚举类
- 枚举类
- 枚举类
- 枚举类
- 枚举类
- 枚举类
- 枚举类
- 枚举类
- 枚举类
- 枚举类
- HTTP协议详解(真的很经典)
- 重学C++ (四) 语句
- ArcSDE空间数据库中SDE用户使用探讨
- ReactNative之开发Mac环境配置
- c#控件说明
- 枚举类
- Educational Codeforces Round 5-A. Comparing Two Long Integers(模拟)
- 使用系统自带CheckBox实现单选效果的2个线性布局切换
- Swift 懒加载
- 上下拉电阻的设计
- Ajax等待返回结果时,弹出一个友好的等待提示
- extjs 架构图
- Android studio 项目没有错误,运行按钮为灰色无法运行,rebuild 和 clean 都没有用
- 代码控制IE11以兼容IE8的模式启动