2010-10-06 72 views
2

根据@Patatoswatter的建议,我创建了一个新的讨论。参考表达式的评估

参考是从@Potatoswatter

this response

考虑的代码片段,

int i = 3, &j = i; 
j = ++ i; 

即我谋上清晰的注释,是这样的。 (这似乎是在我的未测序评价a.k.a序列点的理解的重要缺失的那一块):

@Chubsdad:尽管这是一个别名, 其glvalue评价不 需要我的glvalue评价。 一般而言,评估 参考不需要原始对象在手。有 没理由它应该是UB,所以它使得 感觉应该有一个简单的漏洞 或者转化为不是 的UB代码。

参考不告诉 编译器去看看引用 变量,并得到其左值,因为它 可能不知道什么是变量引用 。编译器计算引用的左值,并且左值标识对象。如果您要 想进一步辩论,请 开个新问题。

在这个问题的任何可能缺乏明确的是“不确定的行为”我通过努力理解“未测序的评价”,“序列点”会的一部分等C++ 0x中。

+0

只是为了修补第一个陈述,“手头上”的意思是“静态确定”。通过“转换为不是UB的代码”,我的意思是将由于对lvalue对象的副作用而产生的UB代码进行处理,其随后不被评估为rvalues,例如'i = ++ i',并将引用变量'j'在这里)复制这样的左值,所以它们的评估不会受名义上的副作用的影响。 – Potatoswatter 2010-10-06 13:18:27

回答

2

想象一下以下

int &i = *new int; 

如果说i是另一名的别名 - 什么名字?一个引用或者引用一个对象或者函数。当你说“glvalue”时,你引用特定表达式的属性,而不是指对象的属性。现在

int i = 0; 
int &ri = i; 

i是一个左值表达和ri是一个左值表达式太(二者句法类别id-expression的)。他们名称(通过名称查找找到)一个参考和一个int变量。

如果您现在确定ri大小写的对象标识,则需要采用该引用并使该表达式引用其初始化的对象。这被称为左值评估,因为您确定了左值(即参考值)的属性。

您需要为i的情况做同样的事情。即你找出左值表达式i所指的是什么对象。因此,ri的glvalue评估与i的glvalue评估不同,尽管它们都产生相同的结果。

Rvalue评估意味着取左值并将左值应用于右值转换。换句话说,要读取一个值。

+0

那么这句话是否仍然正确(如在OP中)? (引用并没有告诉编译器去查看引用的变量并得到它的左值,因为它可能不知道引用了什么变量) – Chubsdad 2010-10-07 05:08:07

+0

@Chubsdad“变量”表示“命名对象”。正如我上面显示的那样,引用可以引用未命名的对象。我认为他的意思是说,引用不像是“链接到编译器的符号表”,而更像是“引用地址”中的指针。 – 2010-10-07 19:57:42

1

从概念上讲,C++中的引用是某个对象的别名或替代名称。当涉及到引用时,这个概念应该引导你理解语言规则。

基本上有实现C++的引用的方法有两种:

  1. 如在编译器的符号表的注释。这是唯一可能的,如果引用只能绑定到一个对象,但它也保持最接近引用的概念。国际海事组织,大多数编译器在可能的情况下使用这种技术,例如这里介绍的例子。
  2. 作为一个指针,在每个操作中自动取消引用。这是后退解决方案,因为它与参考概念不匹配,但它确实使实现参考类型函数参数更容易,而不必严重更改ABI。

在所提出的示例中,存在一个从未方式可以有参考j未绑定到对象i,所以编译器将最有可能使用实施参考的符号表注释方法。这意味着,在声明ij后,它们可以在代码中互换使用,而不会对生成的代码或定义行为的问题产生任何影响。