Rus*_*lan 10 c++ static-assert undefined-behavior
考虑以下代码:
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");
/*...*/
}
Run Code Online (Sandbox Code Playgroud)
在这里,mask将具有type unsigned。假设SomeType是long long。然后,mask由于移动过多,初始化会具有不确定的行为。但是OTOH中有一个static_assert,用于检查在运行时不会发生未定义的行为(因为代码将无法编译)。
但是,由于UB可能导致时间悖论和其他意外事件,因此我不确定static_assert在这种情况下是否可以保证它确实有效。有什么理由可以确定吗?还是应该static_assert在初始化之前重做此代码mask?
由于您知道要用作 的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; /*...*/; /*...*/)
{
/*...*/
}
Run Code Online (Sandbox Code Playgroud)
更简洁的选择是使用辅助函数。
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);
}
Run Code Online (Sandbox Code Playgroud)
并使用
for(auto mask = make_mask(1u, x); /*...*/; /*...*/)
{
/*...*/
}
Run Code Online (Sandbox Code Playgroud)