Lvalues不指定对象在C ++ 14 [英] Lvalues which do not designate objects in 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屋!