Lvalues不指定对象在C ++ 14 [英] Lvalues which do not designate objects in C++14

查看:107
本文介绍了Lvalues不指定对象在C ++ 14的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里使用N3936作为参考(如果任何C ++ 14文本不同,请更正此问题)。

I'm using N3936 as a reference here (please correct this question if any of the C++14 text differs).

在3.10以下和rvalues我们有:

Under 3.10 Lvalues and rvalues we have:


每个表达式都属于此分类中的一个基本分类:lvalue,xvalue或prvalue。

Every expression belongs to exactly one of the fundamental classifications in this taxonomy: lvalue, xvalue, or prvalue.

但是, lvalue 的定义如下:


[...]指定一个函数或对象。

An lvalue [...] designates a function or an object.

在4.1 左值到右值的转换中会出现以下文字:

In 4.1 Lvalue-to-rvalue conversion the text appears:


[... ]在所有其他情况下,转换的结果根据以下规则确定:
[...]
否则,由glvalue指示的对象中包含的值是prvalue结果。 / p>

[...] In all other cases, the result of the conversion is determined according to the following rules: [...] Otherwise, the value contained in the object indicated by the glvalue is the prvalue result.

我的问题是:在左值不指定对象的代码中会发生什么?有两个典型示例:

My question is: what happens in code where the lvalue does not designate an object? There are two canonical examples:

示例1:

int *p = nullptr;
*p;
int &q = *p;
int a = *p;

示例2:

int arr[4];
int *p = arr + 4;
*p;
int &q = *p;
std::sort(arr, &q);

哪些行(如果有)是错误的和/或引起未定义的行为?

Which lines (if any) are ill-formed and/or cause undefined behaviour?

参考例1: * p 一个左值?根据我的第一个报价,它一定是。但是,我的第二个引号排除它,因为 * p 不指定对象。 (它肯定不是一个xvalue或prvalue)。

Referring to Example 1: is *p an lvalue? According to my first quote it must be. However, my second quote excludes it since *p does not designate an object. (It's certainly not an xvalue or a prvalue either).

但是如果你解释我的第二个引号,意味着 * p 实际上是一个左值,完全由左值到右​​值的转换规则。您可以采用所有未由标准定义的行为是未定义的行为的所有规则,但是您必须允许空引用存在,只要没有执行左值到值的转换。

But if you interpret my second quote to mean that *p is actually an lvalue, then it is not covered at all by the lvalue-to-rvalue conversion rules. You may take the catch-all rule that "anything not defined by the Standard is undefined behaviour" but then you must permit null references to exist, so long as there is no lvalue-to-rvalue conversion performed.

历史:此问题在 DR 232 。在C ++ 11中,DR232的分辨率实际上出现了。从N3337引用Lvalue-to-Rvalue转换:

History: This issue was raised in DR 232 . In C++11 the resolution from DR232 did in fact appear. Quoting from N3337 Lvalue-to-rvalue conversion:


如果glvalue引用的对象不是类型T的对象,并且不是从T派生的类型的对象,或者如果对象未初始化,则需要该转换的程序具有未定义的行为。

If the object to which the glvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.

它似乎仍允许存在空引用 - 它只清除了对一个执行左值到右值转换的问题。

which still appears to permit null references to exist - it only clears up the issue of performing lvalue-to-rvalue conversion on one. Also discussed on this SO thread

来自DR232的分辨率不再出现在N3797或N3936中。

The resolution from DR232 no longer appears in N3797 or N3936 though.

推荐答案

不可能创建对null的引用或对数组的不定元素的引用,因为第8.3.2节说(从草案n3936 )

It isn't possible to create a reference to null or a reference to the off-the-end element of an array, because section 8.3.2 says (reading from draft n3936) that


引用应初始化为引用有效的对象或函数。

A reference shall be initialized to refer to a valid object or function.

然而,不清楚,形成具有值类型lvalue的表达式构成引用的初始化。恰恰相反,事实上,临时对象是对象,并且引用不是对象,因此不能说 *(a + n)初始化引用类型的临时对象。

However, it is not clear that forming an expression with a value category of lvalue constitutes "initialization of a reference". Quite the contrary, in fact, temporary objects are objects, and references are not objects, so it cannot be said that *(a+n) initializes a temporary object of reference type.

这篇关于Lvalues不指定对象在C ++ 14的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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