假设有一个悬空引用
甚至更多
x
。只写下面这行代码,是否属于未定义行为?&x;
甚至更多
x;
?
x
。只写下面这行代码,是否属于未定义行为?&x;
x;
?
x + x
。现在我们遇到了标准中另一个不明确的部分。运算符 +
的操作数的值类别没有指定。通常可以从 §5/8 推断出,如果没有指定,则期望 prvalue:
现在因为每当 glvalue 表达式出现为一个运算符的操作数,该运算符期望该操作数为 prvalue 时,将应用 lvalue-to-rvalue(4.1)、array-to-pointer(4.2)或 function-to-pointer(4.3)标准转换将表达式转换为 prvalue。
x
是 lvalue,所以需要进行 lvalue-to-rvalue 转换,这将导致未定义的行为。这是有道理的,因为加法需要访问 x
的值才能计算出结果。&
的结果是该对象的地址。但在这种情况下,没有对象。我不太确定标准实际上是怎么说的。 - Potatoswatteroperator&
在§5.3.1中由一元表达式语义描述。当operator&
被重载时,它会转换为函数调用,并遵循函数调用的规则。 - Joseph Mansfieldstd::vector
的实现方式,它获取存储并根据需要创建/移动/销毁存储中的对象)。 - M.Mx
被初始化为一个有效的对象,然后被销毁,根据§3.8/6规定:— 对此类glvalue应用了lvalue-to-rvalue转换(4.1)
— 使用glvalue访问非静态数据成员或调用对象的非静态成员函数,或
— 将glvalue绑定到虚基类的引用(8.5.3)上,或
— 将glvalue用作dynamic_cast(5.2.7)的操作数或typeid的操作数。
因此,简单地取地址是明确定义的,并且(参考相邻段落)甚至可以生产性地用于创建新对象以替代旧对象。x
,那真的什么也不做,它是&x
的一个合适子表达式。所以也没问题。
x
是一个引用,所以*x
...并不是真正合法的。 - Luchian Grigore