考虑以下代码:
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
是否可以在这种情况下实际运行。有什么理由可以确保这一点吗?还是应该在初始化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; /*...*/; /*...*/)
{
/*...*/
}
较干净的选择是使用助手功能。
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); /*...*/; /*...*/)
{
/*...*/
}
关于c++ - 未定义的行为会影响static_assert吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55031184/