`x [0] == 1`在C ++ 11中的常量表达式,当x是const int []? [英] `x[0] == 1` constant expression in C++11 when x is const int[]?

查看:112
本文介绍了`x [0] == 1`在C ++ 11中的常量表达式,当x是const int []?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的C ++ 11程序是否错误?

  const int x [] = {1,2, 3}; 

static_assert(x [0] == 1,yay);

int main(){}

gcc和clang似乎认为,但是为什么 x [0] == 1 是一个常量表达式?

  x [0] == 1 
下标运算符
*(x + 0)== 1
数组到指针的转换(int * p = x)
*(p + 0)== 1
指针添加
* p == 1
间接(l值y = x [0])
y == 1
左值到右值转换:




非易失性glvalue ,x [0]是一个glvalue和非易失性)的积分(是的,它有类型const int)或枚举类型,指向一个非易失性const对象(是的类型为const int)与前面的初始化1),用常量表达式初始化(​​是1是常量表达式)


似乎为真,<$ c的第一个元素$ c> x 数组符合这些条件。

  1 == 1 





这是一个编译器错误,标准缺陷我缺少一些东西?



5.19 [expr.const]的哪一部分说这不是一个常量表达式?

解决方案

在5.19中:


A [...]涉及以下之一[...]:




  • 一个左值到值的转换到




    • 一个整数或枚举类型的glvalue,指的是具有前面初始化的非易失性const对象,或

    • 一个字面类型的glvalue,指的是使用constexpr定义的非易失性对象,或将
      引用到此类对象的子对象,或

    • 一个字面类型的glvalue,指的是用常量
      表达式初始化的非易失性临时对象



很明显,左值到右值转换只能在常量表达式中进行,如果:




  • 用常量初始化的常量整数(或枚举)声明: const int x = 3; li>
  • 一个包含 constexpr 的声明: constexpr int x [] = {1,2,3};

  • 用常量表达式初始化的临时对象...



您的示例包括lvalue-to-rvalue转换,但没有这些异常,因此 x 不是常量表达式。然而,如果你把它改成:

  constexpr int x [] = {1,2,3} 

static_assert(x [0] == 1,yay);

int main(){}

p>

Is the following C++11 program ill-formed?

const int x[] = {1,2,3};

static_assert(x[0] == 1, "yay");

int main() {}

gcc and clang seem to think so, but why isn't x[0] == 1 a constant expression?

x[0] == 1
subscript operator
*(x+0) == 1
array-to-pointer conversion (int* p = x)
*(p+0) == 1
pointer addition
*p == 1
indirection (lvalue y = x[0])
y == 1
lvalue-to-rvalue conversion:

a non-volatile glvalue (yes, x[0] is a glvalue and non-volatile) of integral (yes it has type const int) or enumeration type that refers to a non-volatile const object (yes it has type const int) with a preceding initialization (yes initialized with 1), initialized with a constant expression (yes 1 is constant expression)

Seems true, the first element of the x array satisfies these conditions.

1 == 1

?

Is this a compiler bug, standard defect, or am i missing something?

What part of 5.19 [expr.const] says this isn't a constant expression?

解决方案

In 5.19:

A [...]expression is a constant expression unless it involves one of the following [...]:

  • an lvalue-to-rvalue conversion (4.1) unless it is applied to

    • a glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding initialization, initialized with a constant expression, or
    • a glvalue of literal type that refers to a non-volatile object defined with constexpr, or that refers to a sub-object of such an object, or
    • a glvalue of literal type that refers to a non-volatile temporary object initialized with a constant expression

Putting it plainly, lvalue-to-rvalue conversion can only be done in constant expressions if:

  • a constant integral (or enum) declaration initialized with a constant: const int x = 3;.
  • a declaration with constexpr: constexpr int x[] = {1,2,3};.
  • a temporary object initialized with a constant expression...

Your example does include lvalue-to-rvalue conversion, but has none of these exceptions, so x is not a constant expression. If, however, you change it to:

constexpr int x[] = {1,2,3};

static_assert(x[0] == 1, "yay");

int main() {}

Then all is well.

这篇关于`x [0] == 1`在C ++ 11中的常量表达式,当x是const int []?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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