英文:
Why is [[assume]] not evaluated but also potentially evaluated?
问题
> cpp > [[assume( expression )]] >
> [...]
> 表达式不会被评估(但仍然可能会被评估)。
这个措辞让我感到困惑。cppreference这里错了吗?
如果它不被评估,为什么它会被可能评估呢?难道它不像sizeof
中的表达式一样是未评估的操作数吗?
如果不是,会有什么后果?
英文:
The cppreference page for [[assume]]
says that:
> cpp
> [[assume( expression )]]
>
> [...]
> the expression is not evaluated (but it is still potentially evaluated).
This wording confuses me. Is cppreference wrong here?
Why would it be potentially evaluated if it's not evaluated? Isn't it an unevaluated operand like the expression in sizeof
?
If not, what are the consequences?
答案1
得分: 10
The C++ standard says virtually the same:
> 标准几乎相同:
The expression is not evaluated. [...]
> 表达式不会被评估。[...]
[- Note 1:* The expression is potentially evaluated ([basic.def.odr]). [...] - end note]
[注释1:* 表达式可能会被评估(basic.def.odr)。[...] - 结束注释]
重要的是,标准规定表达式不会被评估,然而该表达式并非未评估的操作数。措辞经过精心选择,非常重要。
> 除非它是未评估的操作数([expr.context])或其子表达式,或者在此类上下文中的初始化或转换序列中的转换,否则表达式或转换是可能被评估的。
Consequences
结果
As a result [[assume]]
enjoys none of the privileges that unevaluated operands have. To name one example, we cannot refer to non-static data members directly:
因此,[[assume]]
没有未评估的操作数拥有的任何特权。举个例子,我们不能直接引用非静态数据成员:
struct S { int x; };
int main() {
// OK, referring to non-static data members in decltype is possible,
// because its expression is an unevaluated operand
decltype(S::x) x;
// ill-formed, illegal use of S::x in this context
[[assume(S::x > 0)]];
}
这在这种情况下是不合法的,这是对 S::x 的非法使用。
It only makes sense that [[assume]]
is potentially evaluated, because it informs the compiler that a certain runtime expression would evaluate to true
, if it was evaluated, hypothetically.
[[assume]]
只有在可能被评估的情况下才有意义,因为它告诉编译器,如果假设评估了某个运行时表达式,它将评估为true
。
The expression must be something that the compiler could potentially evaluate, even if it never does.
表达式必须是编译器可能会评估的内容,即使它实际上从不这样做。
英文:
The C++ standard says virtually the same:
> The expression is not evaluated. [...]
> [- Note 1: The expression is potentially evaluated ([basic.def.odr]). [...] - end note]
Crucially, the standard says that the expression is not evaluated, however the expression is not an unevaluated operand. The wording is carefully chosen and very important.
> An expression or conversion is potentially evaluated unless it is an unevaluated operand ([expr.context]), a subexpression thereof, or a conversion in an initialization or conversion sequence in such a context.
Consequences
As a result [[assume]]
enjoys none of the privileges that unevaluated operands have. To name one example, we cannot refer to non-static data members directly:
struct S { int x; };
int main() {
// OK, referring to non-static data members in decltype is possible,
// because its expression is an unevaluated operand
decltype(S::x) x;
// ill-formed, illegal use of S::x in this context
[[assume(S::x > 0)]];
}
It only makes sense that [[assume]]
is potentially evaluated, because it informs the compiler that a certain runtime expression would evaluate to true
, if it was evaluated, hypothetically.
The expression must be something that the compiler could potentially evaluate, even if it never does.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论