如果结果不适合目标类型,结果 static_cast 是否为未定义行为

问题描述 投票:0回答:1

我们的代码库中有一个现有函数,如下所示:

template <class OLD_TYPE,class NEW_TYPE>
bool ConvertFromToIsValid(const OLD_TYPE fromValIC, NEW_TYPE & toValOR) noexcept
{
    // Convert to new type
    toValOR = static_cast<NEW_TYPE> (fromValIC);

    // Convert back to OLD type and return true if there was no loss of
    // information.
    return( static_cast<OLD_TYPE> (toValOR) == fromValIC );

} // end ConvertFromToIsValid()

前提是如果该值可以转换为目标类型,则会返回

true
。该代码实际上并未在我们的代码库中的任何地方使用。但我只是尝试使用它,并没有达到预期的效果。

我将其放入godbolt中,发现在-O0时,它按预期工作。在-O1 处,它似乎根本无法正确运行。在 -O2 及更高版本时,它完全优化了对此函数的调用。

我刚刚尝试仔细阅读语言规范。我找不到任何地方指定这将是未定义的行为。

具体来说,我希望

UINT64_MAX
(作为 uint64_t 传递)不能在不损失精度的情况下转换为
double
。但它应该与
long double
一起使用(至少与 x64 的 clang 一起使用)。

我假设 -O0 和 -O2 之间的行为变化表明它是未定义的行为。但就像我说的,我在语言规范中找不到它的说明。

c++ casting c++17 narrowing
1个回答
0
投票

是的,如果在从浮点类型到整型类型的转换中浮点值超出整型类型的范围,则行为未定义。

如果我假设四舍五入到最接近,那就是这种情况,因为

double
可以准确地表示
2**64
并且它是最接近
2**64-1
的可表示值(即测试中的 std::numeric_limits::max()案例)。

但这与

static_cast
无关。这同样适用于隐式转换。

© www.soinside.com 2019 - 2024. All rights reserved.