多个左值等效定义

时间:2017-12-23 23:07:22

标签: c++

Microsoft lvalue定义:

  

左值是指一个持续超出单个对象的对象   表达

second定义:

  

当且仅当E时,表达式E属于lvalue类别   是指ALREADY拥有身份的实体(地址,名称或   别名)使其可以在E之外访问。

我写了以下代码:

class A{};

const A& f1()
{
    return A();
}

const int& f2()
{
    return 1;
}

int main() {
    cout<<&f1()<<endl; // this prints everytime "0".
    cout<<&f2()<<endl; // this prints everytime "0".
    return 0;
}
  1. 为什么f1()f2()lvalue表达式?
  2. 为什么lvalue referencervalue的地址为零?
  3. 为什么两个定义都相同?

3 个答案:

答案 0 :(得分:3)

  
      
  1. 为什么f1()和f2()是左值表达式?
  2.   

因为每个函数都调用一个返回左值引用的函数。

标准草案:[expr.call]

  

11如果结果类型是左值引用类型或...

,则函数调用是左值
  

为什么&amp;类型名称后面的字符使它成为左值引用?

标准草案:[dcl.ref]

  

1在声明T D中,其中D具有任何一种形式

& attribute-specifier-seqopt D1
&& attribute-specifier-seqopt D1
     

并且声明T D1中的标识符的类型是“derived-declarator-type-list T”,然后D的标识符的类型是“T的derived-declarator-type-list reference”...

     

2使用&amp;声明的参考类型被称为左值参考...

  
      
  1. 为什么左值对左值的引用是零?
  2.   

行为未定义。

标准草案:[expr.unary.op]

  

3一元&amp;的结果运算符是...结果具有“指向T的指针”,并且是一个prvalue,它是指定对象的地址

没有指定的对象,在这种情况下,标准没有定义addressof运算符的行为。

标准草案:[defns.undefined]

  

本文档没有要求的行为

     

[注意:当本文档省略任何明确的行为定义时,可能会出现未定义的行为......

  
      
  1. 为什么两个定义都相同?
  2.   

它们不一定相同。其中一个或两个可能不正确。两者似乎都是左值表达式的描述,而不是定义。

规范性定义在C ++标准文档中。

  

标准对lvalue的定义是什么?

标准草案:[basic.lval]

  
      
  • (1.1)glvalue是一个表达式,其评估决定了对象,位域或函数的身份。
  •   

...

  
      
  • (1.3)xvalue是一个glvalue,表示可以重用资源的对象或位字段(通常因为它接近其生命周期的末尾)。   [示例:涉及rvalue引用的某些表达式([dcl.ref])产生xvalues,例如对函数的调用,其返回类型是rvalue引用或强制转换为rvalue引用类型。    - 结束的例子   ]

  •   
  • (1.4)左值是一个不是x值的glvalue。

  •   

[expr]部分定义了语言中的每个可能的表达式,如果表达式是左值,则说明。 &#34;是一个左值&#34;发生了37次,但这种简单的搜索并不一定是详尽无遗的。

答案 1 :(得分:1)

您最终返回挂起引用,因为返回的引用没有任何内容可供引用,因为A()在方法结束时被破坏。你有什么是未定义的行为。 0是占位符,表示它没有引用任何内存位置。 f2()函数返回另一个临时变量作为引用。要绝对清楚它们返回的内存位置是0,因为它们引用的内存位置不再退出。

希望这有帮助。

答案 2 :(得分:1)

使用左值引用返回类型声明一个函数意味着该函数调用是一个左值表达式(仅此而已。)

您链接到的页面在将左值表达式与“已存在”或“持久”等对象等同时都是错误的。在您的代码中是左值表达式的示例,该表达式引用仅在函数调用期间存在的对象。

使用函数调用的结果会导致未定义的行为,因为左值表达式的行为仅在它们实际引用对象时定义。 (加上一些用于引用正在构建或销毁的潜在对象的情况,但这里不适用,因为在调用代码使用表达式结果时,对象的关联存储已经释放)。

未定义的行为意味着任何事情都可能发生,包括(但不限于)输出零。