【发布时间】:2019-03-06 19:52:49
【问题描述】:
考虑以下代码:
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 初始化之前?
【问题讨论】:
-
您可以使用
auto mask = 1u; static_assert(...); mask <<= HAR_BIT*sizeof x-1;完全避免该问题。 -
UB 很棘手。只需将断言移到计算上方以确保它具有正确的值,例如
SomeType x=getX(); static_assert(sizeof(x) < whatever_value_you_need, "Type of numeric parameter is too long"); ... -
@RSahu 我已将示例代码编辑得更简单,更接近我的实际用例。
-
@Ruslan,更新后的代码为在
SomeType x = ...;之后移动static_assert提供了更强有力的理由。在循环中这样做有什么意义? -
我们可以用更多的括号看到这个吗?看到左移、乘法、sizeof 和减法没有任何一个,我有点不高兴。
标签: c++ undefined-behavior static-assert