c++ - 处理可能丢失数据的编译器警告的最优雅方法是什么
问题描述
在我们的大型 C++ 项目中,我们力求没有警告,但人们通常对此很懒惰。我不断修复的一件事是来自如下代码的警告:
sizex = sizey = 32 * c_scale;
给予
警告 C4244:“=”:从“double”转换为“i16”,可能丢失数据
其中 sizex 和 sizey 是 i16 类型,而 c_scale 是双精度类型。
所以我不断将这样的代码行更改为
sizex = sizey = i16(32 * c_scale);
使警告消失。
我会说这会降低代码的可读性,所以我对此并不满意,但在我看来,这比禁用警告要好,也比让一堆警告掩盖可能更严重的警告要好。
任何人都有更优雅或不同的方式来处理这种情况?
解决方案
一些有用的可读性和可维护性指南:
使用标准类型
想象一下我加入了你的项目。我不知道 ani16
是什么,您链接的任何库也不知道。但我确实知道 astd::int16_t
是什么(在 中找到<cstdint>
)。图书馆作家也是如此。
隐藏抽象背后的细节
您在此处描述的操作是将整数缩放某个因子(比如双倍?)。魔鬼在细节中。您不能在不丢失数据的情况下将 double 转换回整数,因此您必须恢复为强制转换,这看起来很混乱,并且会让未来的维护者想知道您在做什么。
所以让我们构建一个抽象:
inline
auto scale_and_round_down(std::int16_t value, double scale) -> std::uint16_t
{
auto scaled_value = value * scale; // answer will be a double
return std::int16_t(value * scale); // round down to nearest int
}
现在我们的代码变成了:
sizex = sizey = scale_and_round_down(32, c_scale);
毫无疑问地表达了意图。在发布版本中, scale_and_round_down
将被内联。您不会为这样的抽象支付任何性能成本。
推荐阅读
- java - 错误显示“XXX 类型的方法 XXX 未定义”...我的 JFrame 有问题吗?
- python - 在 setup.py 中自动发现 Python 子包
- python - 序列化为 namedtuple 会引发“太多值无法解包”
- tensorflow2.0 - 如何在tensorflow2.0中按名称查找变量
- angular - 无法访问功能模块中的 Angular Material
- java - 如何在方法声明中使用类型参数而不是类
- firebase - 您如何在 Firestore 中查看您的读取查询?
- java - 为什么我的方法不附加 csv 文件?
- flutter - 如何用 StatelessWidget 子类中的其他最终成员初始化最终成员?
- c - 使用 pthread 进行锻炼,但我的代码中有一些意外行为