繁体   English   中英

未定义的行为是否会影响static_assert?

[英]Does undefined behavior affect static_assert?

请考虑以下代码:

SomeType x=getX();
for(auto mask = 1u<<(CHAR_BIT*sizeof x - 1);/*...*/;/*...*/)
{
    static_assert(sizeof mask>=sizeof x, "Type of numeric parameter is too long");
    /*...*/
}

这里, mask将具有unsigned类型。 假设SomeType long long 然后,由于过多的移位, mask的初始化将具有未定义的行为。 但OTOH,有一个static_assert ,它检查未定义的行为不能在运行时发生(因为代码无法编译)。

但是由于UB会导致时间悖论和其他意外,我不太确定static_assert能保证在这种情况下实际工作。 有什么理由可以肯定吗? 或者是否应该重做此代码以使mask初始化之前出现static_assert

由于您知道将使用unsigned作为mask类型,因此无需依赖mask来执行static_assert 在循环开始之前立即执行。

SomeType x = getX();
static_assert(sizeof 1u >= sizeof x, "Type of numeric parameter is too long");

for(auto mask = 1u << CHAR_BIT*sizeof x-1; /*...*/; /*...*/)
{
    /*...*/
}

更清洁的选择是使用辅助函数。

template <typename RetType, typename SomeType>
RetType make_mask(RetType in, SomeType const& x)
{
   static_assert(sizeof in >= sizeof SomeType, "Type of numeric parameter is too long");
   return (in << (CHAR_BIT*sizeof SomeType)-1);
}

并使用

for(auto mask = make_mask(1u, x); /*...*/; /*...*/)
{
    /*...*/
}

如果SomeType是一个整数类型,并且您使用的是C ++ 11或更高版本,则可以通过使用以下方法完全消除断言:

auto one = std::make_unsigned<SomeType>::type(1);
for(auto mask = one << CHAR_BIT*sizeof x-1; /*...*/; /*...*/)
{
    /*...*/
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM