数组prvalue的地址

Posted

技术标签:

【中文标题】数组prvalue的地址【英文标题】:Address of array prvalue 【发布时间】:2019-02-14 17:51:32 【问题描述】:

我不明白为什么这不起作用:

auto a = (int[])1, 2, 3, 4, 5;

> error: taking address of temporary array

我知道数组左值在转换为右值时会衰减为指针,但这里的数组已经是右值(实际上是纯右值),因此不需要衰减。我本来希望a 被推导并初始化为int[5]。为什么要取临时地址?

【问题讨论】:

我正在寻找答案,但是。 This 可能是相关的,因为 auto 无法做到这一点。 这个语法是ill-formed。 【参考方案1】:

我本来希望 a 被推导并初始化为 int[5]

遗憾的是,这不是 C 数组的工作方式。数组衰减为指针。您不能真正拥有“数组值”。如果将 auto 替换为推导的类型,则如下所示:

int* a = (int[])1, 2, 3, 4, 5;

衰变必须取地址做指针。

这很容易通过使用引用来解决,因为对临时对象的引用会延长它们的生命周期:

auto&& a = (int[])1, 2, 3, 4, 5; // works!

这是在 compiler explorer 上运行的示例。

当然,使用std::array 你会得到一个很好的语法和值语义:

auto a = std::array1, 2, 3, 4, 5;

【讨论】:

auto a = (const int[])1, 2, 3, 4, 5; 也应该可以工作。 嗨@Unimportant,我得到了与vs141相同的编译器错误,即使是常量。 @lakeweb 也许 vs141 不允许复合文字,严格来说,C++ 不支持。 gcc 允许它们(但在使用-pedantic 编译时会发出警告)。这是与问题中的存储问题不同的问题。 我不明白你的争论链。 std::is_same_v<decltype((int[5])1, 2, 3, 4, 5), int[5]> 返回 true,std::is_same_v<decltype((int*)1, 2, 3, 4, 5), int[5]> 返回 false,那么为什么 auto a = (int[])1, 2, 3, 4, 5; 应该与 int* a = (int[])(1, 2, 3, 4, 5); 相同?我在草稿中找不到找到你论文的那一行。由于int[5] 是一个聚合类型,至少auto a = (int[5])1, 2, 3, 4, 5; 应该可以工作......我的意思是auto aggregate = (A)1, 2, 3, 4, 5; 也适用于每个具有5 个int 成员的聚合类型A。 嗨 @Unimportant ,是的,这不是我第一次遇到 gcc 允许不使用 c++ 的东西,而且微软对此保持严格。谢谢。

以上是关于数组prvalue的地址的主要内容,如果未能解决你的问题,请参考以下文章

lvalue-xvalue-prvalue

C++ lvalue,prvalue,xvalue,glvalue和rvalue详解(from cppreference)

为啥文字不是 const (字符串除外)?

C 语言数组 ( 数组相关地址 | 数组首元素地址 | 数组地址 )

C 语言数组 ( 多维数组操作模型 | 取某个数组元素地址 | 取某个数组元素值 )

数组名不作为数组首地址的两个例外