【问题标题】:Is lvalue-to-rvalue conversion is applied to the array size?左值到右值的转换是否应用于数组大小?
【发布时间】:2022-09-28 12:00:37
【问题描述】:

考虑以下代码:

int main()
{
    const int i = 10;
    int arr[i]{};
}

我需要知道的是,左值到右值的转换是否应用于将左值i 转换为值为10 的纯右值?

我有这种困惑,因为基本上,[expr.const]/8 说:

积分常数表达式是积分的表达式或者 无范围枚举类型,隐式转换为纯右值,在哪里 转换后的表达式是核心常量表达式。

所以这里的整数常量表达式是i,但是它是不是隐式转换为prvalue呢?

正如this answer 中指出的那样:

整数常量表达式隐含的声明 转换为纯右值意味着左值到右值的转换是 应用于任何用作整型常量表达式的表达式。

让我更困惑的是compiler AST 没有显示应用了任何左值到右值的转换。

我需要知道这一点,因为我需要知道转换后的表达式是否是核心常量表达式:如果在这里应用左值到右值,我们必须在[expr.const]/5 中找到一个允许它的异常。

  • 您是否想询问此代码是否合法?如果是这样,那么是的,此代码是合法的。
  • @NathanOliver 您是语言律师标记问题的新手,不是吗?
  • @LanguageLawyer 嗯,不。如您所见,我没有添加缺少引用的答案,我只是添加了评论。评论不需要引用。
  • @OP [expr.const]/5 给你一个问题呢?非易失性左值允许左值到右值的转换。 i 是一个非易失性左值。
  • @LanguageLawyer 你是什么意思?当前文本是左值到右值的转换,除非它应用于 [...] 非易失性左值,它引用可在常量表达式中使用的对象. i 是可用于常量表达式的非易失性左值。

标签: c++ language-lawyer


【解决方案1】:

所以这里的整数常量表达式是i,但是它是隐式转换为prvalue的吗?

是的。

让我更困惑的是compiler AST 没有显示应用了任何左值到右值的转换。

可能您不应该从中得出标准语义的结论,因为这样的 AST 仅仅是实现选择的策略。

那么为什么我需要检查表达式i 是否是核心常量表达式呢?

实际上,i 本身是否是核心常量表达式并没有被检查。在确定数组大小时,仅检查i 的左值到右值转换。

考虑这个例子,c 本身不是核心常量表达式,但是从csize_t 的转换是。同样的原因也适用于 L2R 转换。

#include <cstddef>

struct Conv {
    Conv() {} // not constexpr
    constexpr operator std::size_t() const { return 1; }
};

int main()
{
    Conv c{};
    static_assert(c == 1, "");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 2014-01-17
    相关资源
    最近更新 更多