c – 据我所知,下面的函数不是constexpr,但是代码在clang和g中编译.我失踪了什么

前端之家收集整理的这篇文章主要介绍了c – 据我所知,下面的函数不是constexpr,但是代码在clang和g中编译.我失踪了什么前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在N4140的§5.19/ 2中得到了这个例子:
constexpr int incr(int &n) {
    return ++n;
}

据我所知,这不是一个constexpr函数.但是这段代码在俚语和g中编译.见live example.我在这里缺少什么?

解决方法

在C14中,constexpr函数的规则放松了,文章 N3597: Relaxing constraints on constexpr functions.本文介绍了理论和效果,包括以下(重点是):

As in C++11,the constexpr keyword is used to mark functions which the implementation is required to evaluate during translation,if they are used from a context where a constant expression is required. Any valid C++ code is permitted in constexpr functions,including the creation and modification of local variables,and almost all statements,with the restriction that it must be possible for a constexpr function to be used from within a constant expression. A constant expression may still have side-effects which are local to the evaluation and its result.

和:

A handful of syntactic restrictions on constexpr functions are
retained:

  • asm-declarations are not permitted.
  • try-blocks and function-try-blocks are not permitted.
  • Declarations of variables with static and thread storage duration have some restrictions (see below).

我们可以在N4140第7.1.5节[dcl.constexpr]中找到这个内容

The definition of a constexpr function shall satisfy the following constraints:

  • it shall not be virtual (10.3);

  • its return type shall be a literal type;

  • each of its parameter types shall be a literal type;

  • its function-body shall be = delete,= default,or a compound-statement that does not contain

    • an asm-definition,

    • a goto statement,

    • a try-block,or

    • a definition of a variable of non-literal type or of static or thread storage duration or for which
      no initialization is performed.

最后一个例子显示了如何在constexpr中使用incr:

constexpr int h(int k) {
  int x = incr(k); // OK: incr(k) is not required to be a core
                   // constant expression
  return x;
}

constexpr int y = h(1); // OK: initializes y with the value 2
                        // h(1) is a core constant expression because
                        // the lifetime of k begins inside h(1)

而涵盖k的寿命的规则从h(1)开始就是:

  • modification of an object (5.17,5.2.6,5.3.2) unless it is applied to a non-volatile lvalue of literal type
    that refers to a non-volatile object whose lifetime began within the evaluation of e;

7.1.5 [dcl.constexpr]中的措词告诉我们为什么incr是一个有效的constexpr:

For a non-template,non-defaulted constexpr function or a non-template,non-defaulted,non-inheriting
constexpr constructor,if no argument values exist such that an invocation of the function or constructor
could be an evaluated subexpression of a core constant expression (5.19),the program is ill-formed; no
diagnostic required.

作为T.C的修改示例:

constexpr int& as_lvalue(int&& i){ return i; }

constexpr int x = incr(as_lvalue(1)) ;

显示,我们确实可以使用incr作为核心常数表达式的子表达式,因此它不是不成形的.

猜你在找的C&C++相关文章