在常量表达式中assert是否可用? [英] Is assert usable in constant expressions?

查看:169
本文介绍了在常量表达式中assert是否可用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自< cassert> assert -macro提供了一种确保满足条件的简明方法。如果参数求值为 true ,它不会有任何进一步的效果。但是,在这种情况下,它的调用是否也可以在常量表达式中使用?

解决方案

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2234 =nofollow> LWG 2234 ,在放松之后被引起注意

strong>:



这个词语相对于N3936。


  1. 在17.3
    [definitions]中的现有列表中引入以下新定义:



    常量子表达式 [defns.const.subexpr]



    一个表达式,其作为条件表达式CE (5.16 [expr.cond])的子表达式的求值不会阻止<


  2. / p>

    - ? - 表达式 assert( E 是一个常数子表达式([defns.const.subexpr]),如果




    • NDEBUG 在assert(E)出现的位置或


    • 上下文转换为 bool (4 [conv]),是一个常量子表达式,计算结果为 true p>






常量子表达式



这个解析引入了一个常量子表达式的概念 - 本质上是一个不一定是常量表达式的表达式, 。考虑例如

  constexpr void f(){
int i = 0;
++ i;
}

++ i 不是一个常量表达式,因为它修改一个对象的生命周期超出该表达式(§5.20/(2.15))。但是,表达式 f()完全是一个常量表达式,因为前一点不适用 - i 的生命始于 f 。因此 ++ i 是一个常量子表达式,因为 ++ i 不会阻止 f )作为常量表达式。



assert



该解决方案保证 assert( E 是一个常量子表达式,如果 NDEBUG ,或者参数本身是一个常量子表达式,计算结果为 true 。这意味着对 assert 的调用也可以是一个标准的常数表达式。



形成:

  constexpr int check(bool b){
assert
return 7;
}
constexpr int k = check(true);

b 是常量子表达式, check(true),因此 assert(b) $ c>是一个常量子表达式,因此不会阻止 check(true)



当然,与模板中的 static_assert 相同的缺陷是可能的。鉴于 NDEBUG 未定义,此定义是错误的,§7.1.5/ 5无需诊断:

  constexpr void fail(){
assert(false);
}


The assert-macro from <cassert> provides a concise way of ensuring that a condition is met. If the argument evaluates to true, it shall not have any further effects. However, can its invocation also be used inside a constant expression in that case?

解决方案

This was dealt with by LWG 2234, which was brought back to attention after relaxed constraints on constexpr functions had been introduced.

Proposed resolution:

This wording is relative to N3936.

  1. Introduce the following new definition to the existing list in 17.3 [definitions]:

    constant subexpression [defns.const.subexpr]

    an expression whose evaluation as subexpression of a conditional-expression CE (5.16 [expr.cond]) would not prevent CE from being a core constant expression (5.20 [expr.const]).

  2. Insert a new paragraph following 19.3 [assertions] p1 as indicated:

    -?- An expression assert(E) is a constant subexpression ( [defns.const.subexpr]), if either

    • NDEBUG is defined at the point where assert(E) appears, or

    • E contextually converted to bool (4 [conv]), is a constant subexpression that evaluates to the value true.

Constant subexpressions

This resolution introduced the notion of a constant subexpression - essentially an expression that is not (necessarily) a constant expression in itself, but can be used inside one. Consider for example

constexpr void f() {
    int i = 0;
    ++i;
}

++i is not a constant expression as it modifies an object whose lifetime started outside that expression (§5.20/(2.15)). However, the expression f() is in its entirety a constant expression, because the previous point does not apply - i's lifetime starts in f. Hence ++i is a constant subexpression, as ++i does not prevent f() from being a constant expression.

And assert?

The second part of the resolution guarantees that assert(E) is a constant subexpression if either NDEBUG is defined or the argument is itself a constant subexpression and evaluates to true. This implies that a call to assert can also be a bog-standard constant expression.

The following is well-formed:

constexpr int check(bool b) {
    assert(b);
    return 7;
}
constexpr int k = check(true);

b is a constant subexpression and evaluates to true in the call check(true), hence assert(b) is a constant subexpression and therefore does not prevent check(true) from being one.

Of course, the same pitfall as with static_assert in templates is possible. Given that NDEBUG isn't defined, this definition is ill-formed, no diagnostic required by §7.1.5/5 :

constexpr void fail() {
    assert(false);
}

这篇关于在常量表达式中assert是否可用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆