gpt4 book ai didi

c++ - 为什么 `constexpr const int &a = 1;` 在 block 范围内失败?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:37:24 28 4
gpt4 key购买 nike

N4527 7.1.5[dcl.constexpr]p9

A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized. If it is initialized by a constructor call, that call shall be a constant expression (5.20). Otherwise, or if a constexpr specifier is used in a reference declaration, every full-expression that appears in its initializer shall be a constant expression.

5.20[expr.const]p5

A constant expression is either a glvalue core constant expression whose value refers to an entity that is a permitted result of a constant expression (as defined below), or a prvalue core constant expression whose value is an object where, for that object and its subobjects:

— each non-static data member of reference type refers to an entity that is a permitted result of a constant expression, and

— if the object or subobject is of pointer type, it contains the address of an object with static storage duration, the address past the end of such an object (5.7), the address of a function, or a null pointer value.

An entity is a permitted result of a constant expression if it is an object with static storage duration that is either not a temporary object or is a temporary object whose value satisfies the above constraints, or it is a function.

void foo(){
constexpr const int &a = 1;//error
constexpr static const int &b = 1;//ok in gcc 5.1.0 and clang 3.8.0

}

问题:为什么 constexpr const int &a = 1; 在 block 范围内失败?

最佳答案

这包含在 cwg defect report 2005: Incorrect constexpr reference initialization requirements 中上面写着(强调我的):

Consider an example like:

  constexpr int f() { return 5; } // function must be constexpr
constexpr int && q = f(); // but result is not constant
constexpr int const & r = 2; // temporary is still not constant
int main() {
q = 11; // OK
const_cast< int & >( r ) = 3; // OK (temporary object is not ROMable)

constexpr int && z = 7; // Error? Temporary does not have static storage duration?
}

A constexpr reference must be initialized by a constant expression (7.1.5 [dcl.constexpr] paragraph 9), yet it may refer to a modifiable temporary object. Such a temporary is guaranteed static initialization, but it's not ROMable.

A non-const constexpr reference initialized with an lvalue expression is useful, because it indicates that the underlying storage of the reference may be statically initialized, or that no underlying storage is required at all.

When the initializer is a temporary, finding its address is trivial. There is no reason to declare any intent the computation of its address. On the other hand, an initial value is provided, and that is also required to be a constant expression, although it's never treated as a constant.

The situation is worse for local constexpr references. The initializer generates a temporary when the declaration is executed. The temporary is a locally scoped, unique object. This renders constexpr meaningless, because although the address computation is trivial, it still must be done dynamically.

C++11 constexpr references required initialization by reference constant expressions, which had to “designate an object with static storage duration or a function” (C++11 5.20 [expr.const] paragraph 3). A temporary with automatic storage duration granted by the reference fails this requirement.

C++14 removes reference constant expressions and the static storage requirement, rendering the program well-defined with an apparently defeated constexpr specifier. (GCC and Clang currently provide the C++11 diagnosis.)

Suggested resolution: a temporary bound to a constexpr reference should itself be constexpr, implying const-qualified type. Forbid binding a constexpr reference to a temporary unless both have static storage duration. (In local scope, the static specifier fixes the issue nicely.)

响应是 5.20 第 4 段已经禁止这样做:

This issue is already covered by 5.20 [expr.const] paragraph 4, which includes conversions and temporaries in the analysis.

关于c++ - 为什么 `constexpr const int &a = 1;` 在 block 范围内失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31519935/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com