【问题标题】:The best practice to avoid warning C26451 [Typecast error]避免警告 C26451 [类型转换错误] 的最佳实践
【发布时间】:2021-11-02 14:59:30
【问题描述】:

我正在使用 Visual Studio Community 2019 在 Windows 10 Pro(64 位)上为 C++ 初学者编写编码练习。我想知道类型转换的最佳实践。以下是我尝试过的。你能请任何人给我一些建议吗?提前谢谢你。

我初始化如下:

// "long int" 4 bytes
long m = 2;

// double  8 bytes
double x = 2 * m;

然后我收到警告 C26451:“算术溢出:在 4 字节值上使用运算符'',然后将结果转换为 8 字节值。在调用运算符之前将值转换为更广泛的类型”' 以避免溢出(io.2)。”

所以我更正如下,警告消失了。 除了下面的问题,还有其他方法可以解决问题吗?

// "long int" 4 bytes
long m = 2;

// double  8 bytes
double mConvertToDouble;
mConvertToDouble = static_cast<double>(m);
double x = 2 * mConvertToDouble;

【问题讨论】:

  • 2. * m;,通过将. 放在2 上,它使2 变为双精度,因此m 将在乘法之前自动转换为双精度. (注意m,定义为long将成为int,因为这就是VS对待long的方式)
  • 你为什么要进行这种转换?
  • @ChrisMM 非常感谢您的建议。我尝试了您建议的解决方法,它奏效了!感谢您的帮助。
  • @newbie99 谢谢你的提问。这是因为我收到了如上所述的类型转换错误 C26451。我会回答你的问题吗?
  • @newbie99 我还想练习如何正确地进行类型转换。

标签: c++ visual-studio visual-c++


【解决方案1】:

首先要记住的是C26451 不是“编译器警告”。它来自C++ Core Guidelines checker,它是一个现代的lint-style 工具。

IOW:设计上非常挑剔。您编写的代码实际上是有效的源代码。

C++ Core Guidelines 是 C++ 开发人员的一个很好的指南和一个很好的资源,但其中很多可以总结为“在许多情况下是推荐的,但不是必需的,也可能不是在所有情况下都适合”。

它告诉您的“问题”是在double x = 2 * m; 中,您可能没有意识到它实际上将* 运算符作为32 位单精度执行,然后将其转换为64 位双精度。这可能是一个“可移植性错误”,因为在具有 64 位 long 的架构上,它在边缘情况下的结果与在具有 32 位 long 的 Windows x86/x64 等系统中会产生不同的结果。这也可能是一个“安全漏洞”,因为您会得到不同的“上溢/下溢”行为。

您可以通过多种方式“修复”此问题。如果您真的想要 double,那么正如 cmets 中所述,您应该明确指出 2 旨在作为 double 文字:

double x = 2.0 * m;

您当然也可以在构建中禁用 C++ 核心指南检查器和/或取消特定警告。例如,在我所有的代码库中,我都关闭了C26812: The enum type 'x' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). 警告,因为我不关心它:这是一个建议,如果不破坏我的代码的现有客户端,我就无法遵循它,所以它对我来说只是噪音。

【讨论】:

  • 非常感谢您的回答。这一切对我来说都很有意义。我通读了C++ Core Guidelines checker,我决定不关闭这个功能来学习更好的实践,因为我还是 C++ 的新手,今年 4 月才开始学习这门语言。我感谢您的帮助。我希望你有一个伟大的劳动节周末!
  • @yurachika2020 感谢您对我们的帮助感到满意。如果您的案例已经解决,请帮忙标记答案。
  • @Jeaninez-MSFT 感谢您的建议。我标记了它。我不知道规则。感谢您的帮助!
猜你喜欢
  • 2012-02-19
  • 2019-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-03
  • 1970-01-01
  • 2013-12-07
  • 2018-07-21
相关资源
最近更新 更多