gpt4 book ai didi

c++ - 下标时是否必须使用 constexpr 数组?

转载 作者:IT老高 更新时间:2023-10-28 22:25:25 26 4
gpt4 key购买 nike

给定以下代码:

struct A { static constexpr int a[3] = {1,2,3}; };

int main () {
int a = A::a[0];
int b [A::a[1]];
}

A::a必然odr-usedint a = A::a[0]?


注意:这个问题代表了 a debate in the Lounge 的不那么火爆/不合逻辑/无穷无尽的版本。 .

最佳答案

第一次使用A::a:

int a = A::a[0];

初始化器是一个常量表达式,但这并不能阻止 A::a 在这里被odr-used。而且,确实,A::a 被这个表达式odr-used

从表达式 A::a[0] 开始,我们来看看 [basic.def.odr](3.2)/3(对于 future 的读者,我'我使用 N3936 中的措辞):

A variable x [in our case, A::a] whose name appears as a potentially-evaluated expression ex [in our case, the id-expression A::a] is odr-used unless

  • applying the lvalue-to-rvalue conversion to x yields a constant expression [it does] that does not invoke any non-trivial functions [it does not] and,

  • if x is an object [it is],

    • ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion is applied to e, or e is a discarded-value expression.

那么:e 的可能值有哪些?表达式的潜在结果集是该表达式的一组子表达式(您可以通过阅读 [basic.def.odr](3.2)/2 来检查这一点),所以我们只需要考虑 ex 是子表达式的表达式。它们是:

A::a
A::a[0]

其中,左值到右值的转换不会立即应用于 A::a,因此我们只考虑 A::a[0 ]。根据[basic.def.odr](3.2)/2A::a[0]的潜在结果集合为空,所以A: :a 被这个表达式odr-used

现在,您可以说我们首先将 A::a[0] 重写为 *(A::a + 0)。但这并没有改变:e 的可能值是

A::a
A::a + 0
(A::a + 0)
*(A::a + 0)

其中,只有第四个应用了左值到右值的转换,并且再次,[basic.def.odr](3.2)/2 表示这组潜在结果*(A::a + 0) 为空。特别要注意,数组到指针的衰减不是左值到右值的转换 ([conv.lval](4.1)),即使它转换了数组左值到指针右值——这是数组到指针的转换([conv.array](4.2))。

第二次使用A::a:

int b  [A::a[1]];

根据标准,这与第一种情况没有什么不同。同样,A::a[1] 是一个常量表达式,因此这是一个有效的数组绑定(bind),但是编译器仍然允许在运行时发出代码来计算这个值,并且数组绑定(bind)仍然odr-uses A::a.

请特别注意,常量表达式(默认情况下)是可能求值的表达式。根据[basic.def.odr](3.2)/2:

An expression is potentially evaluated unless it is an unevaluated operand (Clause 5) or a subexpression thereof.

[expr](5)/8 只是将我们重定向到其他子条款:

In some contexts, unevaluated operands appear (5.2.8, 5.3.3, 5.3.7, 7.1.6.2). An unevaluated operand is not evaluated.

这些子条款(分别)说一些 typeid 表达式的操作数、sizeof 的操作数、noexcept 的操作数和decltype 的操作数是未计算的操作数。没有其他类型的未计算操作数。

关于c++ - 下标时是否必须使用 constexpr 数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23428684/

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